# PHP v3.2.X

### Introduction

#### SDK overview

Welcome to the Flagship PHP SDK documentation!

The following article will guide you through the steps to get Flagship up and running on your PHP scripts using our library with preconfigured methods to implement the Decision API or Bucketing CDN.

Feel free to [contact us](mailto:product.feedback@abtasty.com?subject=Flagship%20Developer%20Documentation) if you have any questions regarding this documentation.

#### SDK features

That SDK version helps you :

* Set a [visitor ID](doc:glossary#visitor-id)
* Update [visitor context](doc:glossary#user-context)
* Assign campaigns via the [Decision API](doc:decision-api#campaigns) or the [Bucketing](doc:bucketing) CDN
* Get flags
* Manage visitor consent
* Use experience continuity
* Activate campaigns
* Send hits to our [Universal Collect](doc:universal-collect-documentation)

#### Prerequisites

* **PHP** : version 5.4 or later
* **php\_curl** extension must be enabled
* **json** extension must be enabled
* **Composer** : version 1.0.0 or later
* Your server/device must have an access to the internet.

#### Good to know

* Github repository: <https://github.com/flagship-io/flagship-php-sdk>

### Getting Started

#### Installation

The Flagship PHP SDK can be installed with Composer. Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if the composer is not already installed.

Once composer is installed, in your project root run the following command to install this library:

```shell
composer require flagship-io/flagship-php-sdk
```

#### Initialization

To initialize and start the SDK, simply call the `start` function of the `\Flagship\Flagship` class, in the most appropriate location for your application.

```php
require __DIR__ . '/vendor/autoload.php';

use Flagship\Flagship;

Flagship::start("your_env_id", "your_api_key");
```

| Parameter | Type                                                                              | Description                                  |
| --------- | --------------------------------------------------------------------------------- | -------------------------------------------- |
| envId     | String                                                                            | Environment id provided by Flagship.         |
| apiKey    | String                                                                            | Api authentication key provided by Flagship. |
| config    | <p>- \Flagship\Config\DecisionApiConfig<br>- \Flagship\Config\BucketingConfig</p> | (optional) Custom flagship configuration.    |

**Flagship config**

This class aims to help you to configure the SDK via the following two configurations: DecisionApi and Bucketing. **See**[**Decision Mode**](#decision-mode) **section**.

```php
//Start sdk in Decision api mode.

use Flagship\Config\FlagshipConfig;
use Flagship\Enum\FlagshipStatus;
use Flagship\Enum\LogLevel;
use Flagship\Enum\CacheStrategy;

$config = FlagshipConfig::decisionApi()
    ->setCacheStrategy(CacheStrategy::BATCHING_AND_CACHING_ON_FAILURE)
    ->setLogManager(new CustomLogManager())
    ->setLogLevel(LogLevel::ALL)
    ->setTimeout(2000)
    ->setStatusChangedCallback(function ($status) {
        if ($status === FlagshipStatus::READY) {
            echo "SDK is ready";
        }
    })
  	->setDisableDeveloperUsageTracking(false);

Flagship::start("your_env_id", "your_api_key", $config);
```

```php
//Start sdk in Bucketing mode.

use Flagship\Config\FlagshipConfig;
use Flagship\Enum\FlagshipStatus;
use Flagship\Enum\LogLevel;
use Flagship\Enum\CacheStrategy;

$config = FlagshipConfig::bucketing("http://127.0.0.1:8080/bucketing")
    ->setCacheStrategy(CacheStrategy::BATCHING_AND_CACHING_ON_FAILURE)
    ->setLogManager(new CustomLogManager())
    ->setLogLevel(LogLevel::ALL)
    ->setTimeout(2000)
  	->setFetchThirdPartyData(true)
    ->setStatusChangedCallback(function ($status) {
        if ($status === FlagshipStatus::READY) {
            echo "SDK is ready";
        }
    })
    ->setDisableDeveloperUsageTracking(false);

Flagship::start("your_env_id", "your_api_key", $config);
```

* **`public static function FlagshipConfig::decisionApi() : Flagship\Config\DecisionApiConfig`**

Initialize the SDK to start with [Decision-Api mode](#decision-mode)

\\

* **`public static function FlagshipConfig::bucketing(string $bucketingUrl) : Flagship\Config\BucketingConfig`**

Initialize the SDK to start with [Bucketing-mode](#decision-mode)

| Parameter    | Type   | Description                                                                            |
| ------------ | ------ | -------------------------------------------------------------------------------------- |
| bucketingUrl | string | [flagship-sync-agent](https://github.com/flagship-io/flagship-sync-agent) endpoint URL |

\\

* **`public function setLogManager(Psr\Log\LoggerInterface $logManager) : Flagship\Config\FlagshipConfig`**

  Specify a custom implementation of LogManager in order to receive logs from the SDK.

| Parameter  | Type                    | Description                          |
| ---------- | ----------------------- | ------------------------------------ |
| logManager | Psr\Log\LoggerInterface | Custom implementation of LogManager. |

\\

* **`public function setLogLevel(int $logLevel) : \Flagship\Config\FlagshipConfig`**

This accessor specifies the SDK log filtering level.

| Parameter | Type | Description                                           |
| --------- | ---- | ----------------------------------------------------- |
| level     | int  | Value from `0` to `9` check `\Flagship\Enum\LogLevel` |

Here are the logs informations you'll have for each levels

| Key       | Value | Type | Description                               |
| --------- | ----- | ---- | ----------------------------------------- |
| NONE      | 0     | int  | Logging will be disabled.                 |
| EMERGENCY | 1     | int  | Only emergencies will be logged           |
| ALERT     | 2     | int  | Only alerts and above will be logged.     |
| CRITICAL  | 3     | int  | Only critical and above will be logged.   |
| ERROR     | 4     | int  | Only errors and above will be logged.     |
| WARNING   | 5     | int  | Only warnings and above will be logged.   |
| NOTICE    | 6     | int  | Only notices and above will be logged.    |
| INFO      | 7     | int  | Only info logs and above will be logged.  |
| DEBUG     | 8     | int  | Only debug logs and above will be logged. |
| ALL       | 9     | int  | Everything will be logged.                |

\\

* **`public function setTimeout(int $timeout) : \Flagship\Config\FlagshipConfig`**

  Specify timeout for api request.

| Parameter | Type | Description                                                    |
| --------- | ---- | -------------------------------------------------------------- |
| timeout   | int  | Milliseconds for connect and read timeouts. Default is 2000ms. |

\\

* **`public function setFetchThirdPartyData(bool $fetchThirdPartyData): \Flagship\Config\FlagshipConfig`**

> 📘 3rd party integration
>
> If you use our 3rd party integrations on Flagship, this feature will help you manage your segments in [bucketing mode](https://docs.developers.flagship.io/docs/bucketing)

If you set true, it will fetch the visitor's segment from [universal data connector](https://developers.abtasty.com/docs/data/universal-data-connector) each time fetchFlags is called and append those segments in the visitor context.

| Parameter           | Type | Default | Description |
| ------------------- | ---- | ------- | ----------- |
| fetchThirdPartyData | bool | false   | value       |

\\

**OnVisitorExposed**

In some cases, you'll need to send information about the exposure (When a flag has been seen by your visitor), like sending visitor and flag data to third parties.

To centralize it, we provide a callback in the configuration option of the SDK.

* **`public function setOnVisitorExposed(callable $onVisitorExposed) \Flagship\Config\FlagshipConfig`**

Define a callable to get callback each time a Flag has been exposed to a visitor (When a flag has been seen by your visitor) and succeeded.

| Parameter        | Type     | Description                                                               |
| ---------------- | -------- | ------------------------------------------------------------------------- |
| onVisitorExposed | callable | Callback to trigger when a Flag has been exposed to a visitor and succeed |

```php
<?php

use Flagship\Flagship;
use Flagship\Enum\CacheStrategy;
use Flagship\Config\DecisionApiConfig;
use Flagship\Model\ExposedFlagInterface;
use Flagship\Model\ExposedVisitorInterface;


function onVisitorExposed(ExposedVisitorInterface $visitorExposed, ExposedFlagInterface $fromFlag)
{
    //send to a third party or do your stuff
}

Flagship::start("your_env_id", "your_api_key", DecisionApiConfig::decisionApi()
        ->setCacheStrategy(CacheStrategy::BATCHING_AND_CACHING_ON_FAILURE)
        ->setOnVisitorExposed('onVisitorExposed'));
```

When a callback is triggered, 2 arguments are injected into it:

* ExposedVisitorInterface
* ExposedFlagInterface

**ExposedVisitorInterface**

It's an interface to get information about the visitor to whom the flag has been exposed

```php
<?php

namespace Flagship\Model;

interface ExposedVisitorInterface
{
    /**
     * Visitor id
     * @return string
     */
    public function getId();

    /**
     * visitor anonymous id
     * @return string
     */
    public function getAnonymousId();

    /**
     * visitor context
     * @return array
     */
    public function getContext();
}
```

**ExposedFlagInterface**

It's an interface to get information about the flag that has been exposed.

```php
<?php

namespace Flagship\Model;

use Flagship\Flag\FlagMetadataInterface;

interface ExposedFlagInterface
{
    /**
     * Return the key of flag
     * @return string
     */
    public function getKey();

    /**
     * Return the value of flag
     * @return bool|numeric|string|array
     */
    public function getValue();

    /**
     * Return the metadata of flag
     * @return FlagMetadataInterface
     */
    public function getMetadata();

    /**
     * Return the default value of flag
     * @return bool|numeric|string|array
     */
    public function getDefaultValue();
}
```

Here is an example on how to use this callback:

[Example with Mixpanel integration](https://docs.developers.flagship.io/docs/integrate-with-mixpanel)\
[Example with Segment integration](https://docs.developers.flagship.io/docs/integrate-with-segmentcom)

\\

* **`public function setStatusChangedCallback(callable $statusChangedCallback) \Flagship\Config\FlagshipConfig`**

  Define a callable function to get callback when the SDK status has changed. **See**[**SDK status**](#sdk-status) **section**.

| Parameter             | Type     | Description                                      |
| --------------------- | -------- | ------------------------------------------------ |
| statusChangedCallback | callable | Callback to trigger when SDK status has changed. |

\\

* **`public function setVisitorCacheImplementation(IVisitorCacheImplementation $visitorCacheImplementation) : \Flagship\Config\FlagshipConfig`**

Define an object that implement the interface IVisitorCacheImplementation to handle the visitor cache.\
[see cache-manager](#managing-visitor-cache)

| Parameter                  | Type                                       | Description                                                                        |
| -------------------------- | ------------------------------------------ | ---------------------------------------------------------------------------------- |
| visitorCacheImplementation | Flagship\Cache\IVisitorCacheImplementation | implementation of [IVisitorCacheImplementation](#managing-visitor-cache) interface |

\\

* **`public function setHitCacheImplementation(IHitCacheImplementation $hitCacheImplementation) : \Flagship\Config\FlagshipConfig`**

Define an object that implement the interface IHitCacheImplementation to handle hits cache.\
[see cache-manager](#managing-visitor-cache)

| Parameter              | Type                                   | Description                                                                    |
| ---------------------- | -------------------------------------- | ------------------------------------------------------------------------------ |
| hitCacheImplementation | Flagship\Cache\IHitCacheImplementation | implementation of [IHitCacheImplementation](#managing-visitor-cache) interface |

\\

* **`public function setCacheStrategy(int $cacheStrategy):\Flagship\Config\FlagshipConfig`**

Define the strategy that will be used for hit caching with tracking manager. [see Tracking manager](#tracking_manager)

\\

* **`public function setDisableDeveloperUsageTracking(bool $disableDeveloperUsageTracking ): \Flagship\Config\FlagshipConfig`**

The SDK will collect usage data to help us improve our product

| Parameter                     | Type | Default value | Description                                 |
| ----------------------------- | ---- | ------------- | ------------------------------------------- |
| disableDeveloperUsageTracking | bool | false         | if set true no usage data will be collected |

\\

**Tracking Manger**

The SDK allows you to send hits with a batching system, there is 1 option to configure it : `setCacheStrategy`

The advantage of batch processing with the TrackingManager is to use less network traffic, avoid loss of hits with cache, and catch all hits that would failed and resend them.

All hits will first be added into an internal pool as they are emitted by a visitor. And the pool is going to be emptied by batching all hits and then sending the batch when the static method `Flagship::close()` is called.

If a batch fails, all of the hits inside the failed batch will be cached depending on the cache strategy used and can be resent later.

**Note:** At any time, when your app (script) is about to **terminate** or **crash**, you must call [`Flagship::close()`](#close-function) to batch and send all hits that are in the pool.

**options:**

**CacheStrategy**

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Default value
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    1
  </td>

  <td style={{ textAlign: "left" }}>
    [**Recommended**] When a hit is emitted, it will first be added into the pool, then batched and sent when the method `Flagship::close()` is called. If the batch send failed all hits inside will be cached in database using [IHitCacheImplementation](#hit-cache).  

    [see example using redis](#continuous_strategy)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    NO\_BATCHING\_AND\_CACHING\_ON\_FAILURE
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    2
  </td>

  <td style={{ textAlign: "left" }}>
    [**Default value**] When a hit is emitted, it will be sent directly. If the hit sending failed all hits inside will be cached in database using [IHitCacheImplementation](#hit-cache).  

    Hits are sent as they are emitted.  

    * \*Note\*\*: This strategy uses a little more network traffic than the first because each hit emitted will send an http request.
  </td>
</tr>
```

| Key                                         |
| ------------------------------------------- |
| BATCHING\\\_AND\\\_CACHING\\\_ON\\\_FAILURE |

Example

```php
use Flagship\Config\FlagshipConfig;
use Flagship\Enum\CacheStrategy;

$config = FlagshipConfig::decisionApi()
    ->setCacheStrategy(CacheStrategy::BATCHING_AND_CACHING_ON_FAILURE);

Flagship::start("your_env_id", "your_api_key", $config);

//Create visitor
//Get your flag 
//Send your hits
//Do your stuff 

//Call before terminating 
Flagship::close();
```

\\

***Only available for Bucketing:***

**Bucketing file url**

* **`public function setBucketingUrl(string $bucketingUrl): \Flagship\Config\BucketingConfig`**

  Define the [flagship-sync-agent](https://github.com/flagship-io/flagship-sync-agent) endpoint URL where the SDK will fetch the bucketing file from polling process

| Parameter    | Type   | Description                      |
| ------------ | ------ | -------------------------------- |
| bucketingUrl | string | flagship-sync-agent endpoint URL |

\\

**Decision Mode**

**`DecisionApi`Mode**

When the SDK is running in `DecisionApi` mode, the campaign assignments and targeting validation take place server-side. In this mode, each call to the `fetchFlags` method to refresh the modifications will create an HTTP request.

**`Bucketing`Mode**

In `Bucketing` mode, when `fetchFlags` method is called. The SDK will check the `bucketing file` fetched through [**flagship-sync-agent endpoint URL**](#bucketing_file_url) . Then validates campaigns targeting the visitor and assigns a variation. [**Learn more**](https://github.com/flagship-io/Gitbook/blob/main/docs/bucketing/README.md)

In order to feed `bucketing file`, you must run bucketing polling process. **See**[**Bucketing polling**](#bucketing-polling) **section**.

\\

**SDK Status**

List of possible SDK status :

class `Flagship\Enum\FlagshipStatus`

| Status                           | type | Description                                                                                                                                |
| -------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| FlagshipStatus::NOT\_INITIALIZED | int  | Flagship SDK has not been started or initialized successfully.                                                                             |
| FlagshipStatus::STARTING         | int  | Flagship SDK is starting.                                                                                                                  |
| FlagshipStatus::READY\_PANIC\_ON | int  | Flagship SDK is ready but is running in Panic mode: All visitors features are disabled except 'synchronization' which refresh this status. |
| FlagshipStatus::READY            | int  | Flagship SDK is ready to use.                                                                                                              |

\\

### Bucketing polling

To start bucketing polling, you need to run in your infrastructure [**flagship-sync-agent**](https://github.com/flagship-io/flagship-sync-agent). This binary is a local endpoint (API) that provides the bucketing file which is downloaded from flagship CDN by performing the bucketing polling process.

[**flagship-sync-agent**](https://github.com/flagship-io/flagship-sync-agent) downloads all the campaigns configurations at once in a single bucketing file and stored it in cache. It will only be downloaded again when campaign configurations are modified in the Flagship interface.

The gain of going through flagship-sync-agent is in terms of response time. once it has downloaded the bucketing file, it delivers it within a very short time to the script that requests it.

You can download it [**here**](https://github.com/flagship-io/flagship-sync-agent)

```shell
$ ./app --envId=YOUR_ENV_ID --pollingInterval=2000 --port=3000 --address=0.0.0.0
```

arguments:

| argument        | type   | description                                                            |
| --------------- | ------ | ---------------------------------------------------------------------- |
| envId           | string | Environment id provided by Flagship.                                   |
| pollingInterval | int    | Define time interval between two bucketing updates. Default is 2000ms. |
| Port            | int    | Endpoint listen port. Default is 8080                                  |
| address         | string | Address where the endpoint is served. Default is 0.0.0.0               |

### Docker

```shell
docker pull flagshipio/sync-agent

env FS_ENV_ID="YOUR_ENV_ID" docker run -p 3000:8080 -e FS_ENV_ID flagshipio/sync-agent
```

Environment variables:

| argument              | type   | description                                                            |
| --------------------- | ------ | ---------------------------------------------------------------------- |
| FS\_ENV\_ID           | string | Environment id provided by Flagship.                                   |
| FS\_POLLING\_INTERVAL | int    | Define time interval between two bucketing updates. Default is 2000ms. |
| FS\_PORT              | int    | Endpoint listen port. Default is 8080                                  |
| FS\_ADDRESS           | string | Address where the endpoint is served. Default is 0.0.0.0               |

### API docs

| route          | Description                                           |
| -------------- | ----------------------------------------------------- |
| /bucketing     | Get the Json bucketing file                           |
| /health\_check | Return http code 200 to check if the sync agent is up |

\\

#### Other `Flagship` class methods

**`close` function**

Every time your application (script) is about to **terminate** or to crash, you must call the static `close` method of the Flagship class to batch and send all hits that are in the pool.

* **`public static function Flagship::close(): void`**

\\

**`getConfig` function**

Return the current config used by the SDK. [see configuration](#flagship-config)

* **`public static function Flagship::getConfig(): FlagshipConfig`**

\\

**`getStatus` function**

Return current status of Flagship SDK. [see`FlagshipStatus`](#sdk-status)

* **`public static function Flagship::getStatus(): int`**

\\

### Create a new visitor

The `\Flagship\Visitor\Visitor` instance is an helper object that lets you manage the context and campaigns for a visitor identified by a unique ID.

The visitor context is a property dataset which defines the current visitor of your app. This dataset is sent and used as targeting criteria for campaign assignment.

For example, if you want to enable or disable a specific feature based on a `VIP` status, you would pass this attribute as a key-value pair in the visitor context so that the Decision API can enable or disable the corresponding feature flag for the visitor.

```php
use Flagship\Flagship;

$visitor = Flagship::newVisitor("your_visitor_id")
        ->hasConsented(true)
        ->withContext(["age" => 31, "isVip" => true])
        ->isAuthenticated(true)
        ->build();
```

\\

* **`public static function newVisitor(string $visitorId) : \Flagship\Visitor\VisitorBuilder`**

  Initialize the builder and Return a [`\Flagship\Visitor\VisitorBuilder`](#visitorbuilder)

  | Parameter | Type   | Description                |
  | --------- | ------ | -------------------------- |
  | visitorId | string | Unique visitor identifier. |

\\

#### VisitorBuilder

`\Flagship\Visitor\VisitorBuilder` is a fluent interface builder api managing Visitor creation.

* **`public function isAuthenticated(bool $isAuthenticated) : \Flagship\Visitor\VisitorBuilder`**

  Specify if the Visitor is authenticated or anonymous.

  | Parameter       | Type | Description                                                        |
  | --------------- | ---- | ------------------------------------------------------------------ |
  | isAuthenticated | bool | true for an authenticated visitor, false for an anonymous visitor. |

\\

* **`public function hasConsented(bool $hasConsented = true) : \Flagship\Visitor\VisitorBuilder`**

  Specify if the Visitor has consented for personal data usage. When false some features will be deactivated, cache will be deactivated and cleared.

  | Parameter    | Type | Description                                                  |
  | ------------ | ---- | ------------------------------------------------------------ |
  | hasConsented | bool | Set to true when the visitor has consented, false otherwise. |

\\

* **`public function withContext(array $context) : \Flagship\Visitor\VisitorBuilder`**

  Specify Visitor initial context key / values used for targeting.

  | Parameter   | Type                      | Description                                                                           |
  | ----------- | ------------------------- | ------------------------------------------------------------------------------------- |
  | withContext | array (associative array) | <p>visitor initial context.<br>e.g: \["age"=>42, "IsVip"=>true, "country"=>"UK"].</p> |

> 🚧
>
> * Visitor context keys must have a type of `string`
> * Visitor context values must have a type of `string`, `bool`, `numeric`
> * Visitor context keys and values are **case sensitive**

\\

* **`public function build() : \Flagship\Visitor\Visitor`**

  Complete the Visitor Creation process and return an instance of `\Flagship\Visitor\Visitor`

\\

### Updating the visitor context

The visitor context is a property dataset that defines the current visitor of your app. This dataset is sent and used as targeting criteria for campaign assignment.

The following method from the `\Flagship\Visitor\Visitor` instance allows you to set new context values matching the given keys.

```php
use Flagship\Flagship;

  Flagship::start("your_env_id", "your_api_key");

  $visitor = Flagship::newVisitor("your_visitor_id")
              ->withContext(["age" => 31, "isVip" => true])
              ->build();

  $visitor->updateContext("lastPurchaseDate", 1615384464);
```

\\

**`public function updateContext(string $key, bool|numeric|string $value) : void`**

Update the visitor context values matching the given keys. If the key doesn't exist in the visitor's context, it will be added.

| Parameter | Type                      | Description    |
| --------- | ------------------------- | -------------- |
| key       | String                    | Context key.   |
| value     | bool or numeric or string | Context value. |

\\

**`public function updateContextCollection(array $Context) : void`**

Update the visitor context values matching the given keys. If a key doesn't exist in the visitor's context, it will be added.

| Parameter | Type                      | Description                 |
| --------- | ------------------------- | --------------------------- |
| context   | array (associative array) | collection of keys, values. |

\\

**`public function getContext(): array`**

Get all the visitor's current context as a collection of keys, values

**`public function clearContext() : void`**

Clear the actual visitor context

\\

> 🚧
>
> * Visitor context keys must have a type of `string`
> * Visitor context values must have a type of `string`, `bool`, `numeric`
> * Visitor context keys and values are **case sensitive**

#### update context with predefined keys of context

```php
use Flagship\Flagship;
use Flagship\Enum\FlagshipContext;

Flagship::start("your_env_id", "your_api_key");
$visitor = Flagship::newVisitor("your_visitor_id")
              ->context(["age" => 31, "isVip" => true])
              ->build();

$visitor->updateContext(FlagshipContext::OS_NAME, "linux");
$visitor->updateContext(FlagshipContext::IP, "127.0.0.1");
```

[**Learn more**](#predefined-visitor-context-keys--flagshipenumflagshipcontext) about predefined keys of context

### Managing visitor campaigns

#### Fetching Flags

The `fetchFlags()` method of the `\Flagship\Visitor\Visitor` instance, according to [**Decision Mode**](#decision-mode), will either automatically call the Flagship Decision API to run campaign assignments according to the current visitor context and retrieve applicable flags; or check the `bucketing file`, validate campaigns targeting the visitor, assign a variation and retrieve applicable flags

These flags are then stored in the SDK and updated synchronously when `fetchFlags()` is called.

```php
use Flagship\Flagship;

Flagship::start("your_env_id", "your_api_key");

$visitor = Flagship::newVisitor("your_visitor_id")->build();

$visitor->updateContext("postcode", "31200");

$visitor->fetchFlags();
```

**`public function fetchFlags() : void`**

In DecisionApi Mode this function calls the Flagship Decision API to run campaign assignments according to the current visitor context and retrieve applicable flags.\
In bucketing Mode, it checks the bucketing file, validates campaigns targeting the visitor, assigns a variation, and retrieves applicable flags.

#### Getting flags

Once the campaign has been **assigned** and **fetched**, all the flags are stored in the SDK. You can retrieve these flags using the following functions from the `\Flagship\Visitor` instance:

```php
use Flagship\Flagship;

Flagship::start("your_env_id", "your_api_key");
$visitor = Flagship::newVisitor("your_visitor_id")->build();
$visitor->updateContext("isVip", true);
$visitor->fetchFlags();

$flag = $visitor->getFlag("displayVipFeature", false);
```

\\

**`getFlag` function**

Return a [Flag](#flag-class) object by its key. If no flag match the given key an empty flag will be returned. Call [exists()](#check-if-a-flag-exists) to check if the flag has been found.

* **`public function getFlag(string $key, bool|numeric|string|array $defaultValue) : \Flagship\Flag\FlagInterface`**

| Argument     | Type                         | Description                |
| ------------ | ---------------------------- | -------------------------- |
| key          | string                       | Key associated to the flag |
| defaultValue | bool\|numeric\|string\|array | Flag default value         |

> 🚧
>
> * Default value must be one of the following type : `string`, `bool`, `numeric`, `array`.

\\

#### Getting flags current value

**`getValue` function**

To retrieve [flag](#flag-class) current value, simply call getValue() method of the Flag object.

\\

```php
use Flagship\Flagship;

Flagship::start("your_env_id", "your_api_key");
$visitor = Flagship::newVisitor("your_visitor_id")->build();
$visitor->updateContext("isVip", true);
$visitor->fetchFlags();

$flagValue = $visitor->getFlag("displayVipFeature", false)->getValue();
```

* **`public function getValue(bool $visitorExposed) : bool|numeric|string|array`** function

Returns the value from the assigned campaign variation or the Flag default value if the Flag does not exist, or if types are different.

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Default Value
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    Boolean
  </td>

  <td style={{ textAlign: "left" }}>
    true
  </td>

  <td style={{ textAlign: "left" }}>
    Tells Flagship the visitor have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting.\
    If needed it is possible to set this param to false and call `visitorExposed()` afterward when the visitor sees it.
  </td>
</tr>
```

| Parameter      |
| -------------- |
| visitorExposed |

\\

#### Getting flags campaigns metadata

**`getMetadata` function**

Retrieve campaigns metadata for a specific Flag.

```php
use Flagship\Flagship;

Flagship::start("your_env_id", "your_api_key");
$visitor = Flagship::newVisitor("your_visitor_id")->build();
$visitor->updateContext("isVip", true);
$visitor->fetchFlags();

$campaignMetada = $visitor->getFlag("displayVipFeature", false)->getMetadata();
```

\\

* **`public function getMetadata() : FlagMetadata`**

Return the campaign information metadata or an empty object if the Flag doesn't exist or if the default value type does not correspond to the Flag type in Flagship.

The `FlagMetadata` class has the following shape:

| getters               | Type    | Description                              |
| --------------------- | ------- | ---------------------------------------- |
| getCampaignId         | string  | Campaign ID                              |
| getCampaignName       | string  | Campaign name                            |
| getVariationGroupId   | string  | Variation group ID                       |
| getVariationGroupName | string  | Variation group name                     |
| getVariationId        | string  | The variation ID assigned to the visitor |
| getVariationName      | string  | Variation name                           |
| getIsReference        | boolean | Specify if its the reference variation   |
| getCampaignType       | string  | campaign type                            |
| getSlug               | string  | campaign slug                            |

\\

#### Report a Flag exposure

> 🚧 Deprecated
>
> The userExposed method is deprecated since the version 3.1.1. please use visitorExposed instead.

**`visitorExposed` function**

By default when the method [getValue()](#getvalue-function) is called, The SDK considers that the visitor have seen the effets of your Flag, unless you pass false to getValue(). In this case you will have to call visitorExposed().

There are two ways for exposing a visitor to a flag:

1. Pass an `visitorExposed = true` parameter to the [**getValue()**](#getvalue-function) method.
2. Use the following **visitorExposed()** method from the Flag instance.

```php
use Flagship\Flagship;

Flagship::start("your_env_id", "your_api_key");
$visitor = Flagship::newVisitor("your_visitor_id")->build();
$visitor->updateContext("isVip", true);
$visitor->fetchFlags();

$visitor->getFlag("displayVipFeature", false);

//Later

$visitor->visitorExposed()
```

* **`public function visitorExposed() : void`**

Tells Flagship the visitor have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting. No visitor exposure will be sent if the Flag doesn't exist or if the default value type do not correspond to the Flag type in Flagship.

\\

#### Check if a Flag exists

**`exists` function**

This method will return true if a Flag exists in Flagship

* **`public function exists() : bool`**

\\

```php
use Flagship\Flagship;

Flagship::start("your_env_id", "your_api_key");
$visitor = Flagship::newVisitor("your_visitor_id")->build();
$visitor->updateContext("isVip", true);
$visitor->fetchFlags();

$exists = $visitor->getFlag("displayVipFeature", false)->exist();
```

\
\\

### Managing visitor consent

The `\Flagship\Visitor\Visitor` class provides a method to let you manage visitor consent for data privacy usage. When False, ***campaign activation*** and ***hits*** will be disabled.

```php
use Flagship\Flagship;

Flagship::start("your_env_id", "your_api_key");
$visitor = Flagship::newVisitor("your_visitor_id")->build();
$visitor->setConsent(false);
```

**`public function setConsent(bool $hasConsented) : \Flagship\Visitor\Visitor`**

| Parameter    | Type | Description                                                                               |
| ------------ | ---- | ----------------------------------------------------------------------------------------- |
| hasConsented | bool | Set visitor consent for private data usage. When false some features will be deactivated. |

**`public function hasConsented() : bool`**

Return `true` if the visitor has consented for private data usage, otherwise, return `false`.

> 📘
>
> When a visitor sets consent to false, the data collection features (visitorExposed and sendHit) will be deactivated for them and all hits related to the visitor will be flushed from the pool and the cache.

\\

### Experience Continuity

Dealing with anonymous and logged-in visitors, experience continuity allows you to maintain consistency between sessions and devices.

> 🚧
>
> Make sure that the experience continuity option is enabled on the flagship platform before using those methods.

#### Authenticate

**`public function authenticate(string $visitorId) : void`**

| Parameter | Type   | Description                          |
| --------- | ------ | ------------------------------------ |
| visitorId | string | id of the new authenticated visitor. |

> 🚧
>
> Because we have changed the visitor data, we have to call the fetchFlags method after calling this one to update the decision from Flagship.
>
> The targeting / Flags could be different for the visitor.

#### Unauthenticate

**`public function unauthenticate() : void`**

> 🚧
>
> Because we have changed the visitor datas, we have to call the fetchFlags method after calling this one to update the decision from Flagship.
>
> The targeting / Flags could be different for the visitor.

#### Code example

Let's assume basic scenario to understand how things work:

**1. Your visitor arrives on your app for the first time.**

We need to initialize the visitor but as we don't know anything about this visitor, we'll create a random visitor id or let the SDK do it for us. You can also specify some visitor context if necessary.

```php
$visitor = Flagship::newVisitor()->withContext([ "key"=> "value"])->build();
```

Here we don't set visitorId property so the SDK has auto-created an id for our visitor.

Regardless of how it has been set, the actual visitor id will be what we call the anonymous id.

**2. Your visitor is signing in.**

To tell the SDK about this status modification, you'll have to call the authenticate function which takes the required visitor id as argument.

```php
// Example 
  // You fetch the visitor_id from your DB
  // $visitor_id = $db->getUserId();

  $visitor->authenticate("visitor_id");
  
  // Since your visitor has changed (is now logged-in)
  // You have to check if the proper targeting and flags are set

	$visitor->fetchFlags();
```

The visitor is updated as authenticated, keeping the previous variations from campaigns that are still matched and thus gives you same flags as before being logged in.

> 📘
>
> Keep in mind that if the visitor also has its context changed, you might still have changes on flags as your visitor might target new campaigns.

**3. Your visitor decides to sign out.**

If you want to keep the same visitor experience, then you should do:

```php
$visitor->unauthenticate();

  // Since your visitor has changed (is now logged-out)
  // You have to check if the proper targeting and flags are set

	$visitor->fetchFlags();
```

### Hit Tracking

This section helps you track your visitors in your application and learn how to build hits in order to feed your reports. For more information about our measurement protocol, read our [Universal Collect documentation](doc:universal-collect-documentation).

There are four different types of Hits available:

* Page
* Transaction
* Item
* Event

**They must all be built and sent with the following function from the`Flagship\Visitor` instance:**

```php
use Flagship\Flagship;
use Flagship\Hit\Page;

$visitor = Flagship::newVisitor("your_visitor_id")->build();

$visitor->sendHit(new Page("https://www.my_domain_com/my_page"));
```

**`public function sendHit(HitAbstract $hit) : void`**

Send Hit to Flagship servers for reporting.

| Parameter | Type        | Description  |
| --------- | ----------- | ------------ |
| hit       | HitAbstract | Hit to send. |

#### Hit common optional parameters

```php
use Flagship\Flagship;
use Flagship\Hit\Page;

$visitor = Flagship::newVisitor("your_visitor_id")->build();

$visitor->sendHit(new Page("https://www.my_domain_com/my_page")
          ->setUserIp("127.0.0.1")
          ->setScreenResolution("800X600")
          ->setLocale("fr")
          ->setSessionNumber("12345")
          );
```

| Builder Parameter   | Type   | Description        |
| ------------------- | ------ | ------------------ |
| setUserIp           | String | Visitor IP         |
| setScreenResolution | string | Screen resolution. |
| setLocale           | String | visitor language   |
| setSessionNumber    | string | Session number     |

#### Page

This hit should be sent each time a visitor arrives on a new page.

```php
use Flagship\Hit\Page;

$page = new Page("https://www.my_domain_com/my_page");

$visitor->sendHit($page);
```

**`public Page(string $pageUrl)`**

| Builder Parameter | Type   | Description |
| ----------------- | ------ | ----------- |
| pageUrl           | String | Valid url.  |

#### Transaction

This hit should be sent when a visitor completes a transaction.

```php
use Flagship\Hit\Transaction;

$transaction = (new Transaction("#12345", "affiliation"))
            ->setCouponCode("code")
            ->setCurrency("EUR")
            ->setItemCount(1)
            ->setPaymentMethod("creditCard")
            ->setShippingCosts(9.99)
            ->setTaxes(19.99)
            ->setTotalRevenue(199.99)
            ->setShippingMethod("1day");

$visitor->sendHit($transaction);
```

**`public Transaction(string $transactionId, string $affiliation)`**

| Builder Parameter | Type   | Description                                                                                                             |
| ----------------- | ------ | ----------------------------------------------------------------------------------------------------------------------- |
| transactionId     | String | Unique identifier for your transaction.                                                                                 |
| affiliation       | String | The name of the KPI that you will have inside your reporting. [**Learn more**](doc:glossary#kpi)                        |
| setTotalRevenue   | float  | Specifies the total revenue associated with the transaction. This value should include any shipping and/or tax amounts. |
| setShippingCosts  | float  | The total shipping cost of your transaction.                                                                            |
| setShippingMethod | String | The shipping method for your transaction.                                                                               |
| setTaxes          | float  | Specifies the total amount of taxes in your transaction.                                                                |
| setCurrency       | String | Specifies the currency of your transaction. NOTE: This value should be a valid ISO 4217 currency code.                  |
| setPaymentMethod  | String | Specifies the payment method used for your transaction.                                                                 |
| setItemCount      | int    | Specifies the number of items in your transaction.                                                                      |
| setCouponCode     | String | Specifies the coupon code used by the customer in your transaction.                                                     |

#### Item

This hit is used to link an item with a transaction. It must be sent **after** the corresponding transaction hit.

```php
use Flagship\Hit\Item;

$item = (new Item("#12345", "product", "sku123"))
            ->setItemCategory("test")
            ->setItemPrice(199.99)
            ->setItemQuantity(1);

$visitor->sendHit($item);
```

**`public Item(string $transactionId, string $productName, string $productSku)`**

| Builder Parameter | Type   | Description                                      |
| ----------------- | ------ | ------------------------------------------------ |
| transactionId     | String | Unique identifier for your transaction.          |
| productName       | String | Name of your item.                               |
| productSku        | String | Specifies the SKU or item code.                  |
| setItemCategory   | String | Specifies the category that the item belongs to. |
| setItemPrice      | float  | Specifies the price for a single item/unit.      |
| setItemQuantity   | int    | Specifies the number of items purchased.         |

#### Event

This hit can be used for any event (e.g. Add To Cart click, newsletter subscription).

```php
use Flagship\Hit\Event;

$event = (new Event(EventCategory::USER_ENGAGEMENT, "action"))
              ->setLabel("label")
              ->setValue(100);

$visitor->sendHit($event);
```

**`public Event(EventCategory category, String action)`**

| Builder Parameter | Type          | Description                                                                                                                                                                                  |
| ----------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| category          | EventCategory | Specifies the category of your event. NOTE: This value must be either **`Flagship\Enum\EventCategory::ACTION_TRACKING`** or **`Flagship\EnumEventCategory::USER_ENGAGEMENT`**.               |
| action            | String        | Event name that will also serve as the KPI that you will have inside your reporting. [**Learn more**](doc:glossary#kpi)                                                                      |
| setLabel          | String        | (optional) Additional description of your event.                                                                                                                                             |
| setValue          | Integer       | <p>(optional) Can be used to evaluate visitor interactions with individual site objects or content items.<br><strong>NOTE</strong>: <em>this value must be non-negative / non-float</em></p> |

### Managing visitor cache

The purpose of the cache management is to answer the following needs:

* **Re-allocation in bucketing mode :**

In bucketing mode and with the cache enabled, the SDK will always keep visitor in the variation he was allocated first, in case the customer manually changed the traffic allocation or the `dynamic allocation` feature was enabled, to avoid user experience issues. Indeed in bucketing mode the assignation is made on local devices so changing traffic allocation in the platform could authorize the visitors to see different variations.

* **Handle offline mode :**

With the cache enabled, the SDK will try to retrieve the latest visitor data (campaign assignations) from the cache.

To use the cache manager the intefaces `IVisitorCacheImplementation` must be implemented through visitorCacheImplementation property accessor of [configuration](#flagship-config).

#### Visitor Cache

The visitor cache is used to store the visitor data in a database through the `Flagship\Cache\IVisitorCacheImplementation` interface.

```php
interface IVisitorCacheImplementation
{
    public  function cacheVisitor($visitorId, array $data) : void;

    public function lookupVisitor($visitorId) : array;

    public function flushVisitor($visitorId) : void;
}
```

**`cacheVisitor` function**

This method is called when the SDK needs to cache visitor information in your database.

* `public function cacheVisitor($visitorId, array $data) : void`

It has 2 arguments :

| Argument  | Type   | Description                                                                   |
| --------- | ------ | ----------------------------------------------------------------------------- |
| visitorId | string | visitor ID                                                                    |
| data      | array  | visitor data. The array has the follows shape [`see`](#visitor-cache-format). |

**`lookupVisitor` function**

This method is called when the SDK needs to get the visitor information corresponding to visitor ID from your database.

It has to return an array which follows this shape [see](#visitor-cache-format).

* `public function lookupVisitor($visitorId) : array`

It has one argument :

| Argument  | Type   | Description |
| --------- | ------ | ----------- |
| visitorId | string | visitor ID  |

**`flushVisitor` function**

This method is called when the SDK needs to erase the visitor information corresponding to visitor ID in your database.

It will be called every time [`setConsent`](#managing-visitor-consent) get false.

* `public function flushVisitor($visitorId) : void`

It has one argument :

| Argument  | Type   | Description |
| --------- | ------ | ----------- |
| visitorId | string | visitor ID  |

> 📘
>
> * `flushVisitor` method will be called every time [`setConsent`](#managing-visitor-consent) get false.

**Visitor Cache format**

```php
[
  'Version' => 1,
  'Data' => [
    'VisitorId' => 'visitor_1',
    'AnonymousId' => NULL,
    'Consent' => true,
    'Context' => [
      'qa_getflag' => true,
      'fs_client' => '.NET',
      'fs_version' => 'V3',
    ],
    'AssignmentsHistory' => [
      'xxxxxxxxxxxxxxxxxxxx' => 'xxxxxxxxxxxxxxxxxxxx',
      'yyyyyyyyyyyyyyyyyyyy' => 'yyyyyyyyyyyyyyyyyyyy',
    ],
    'Campaigns' => [
      0 => [
        'CampaignId' => 'xxxxxxxxxxxxxxxxxxxx',
        'VariationGroupId' => 'xxxxxxxxxxxxxxxxxxxx',
        'VariationId' => 'xxxxxxxxxxxxxxxxxxxx',
        'IsReference' => false,
        'Type' => 2,
        'Activated' => false,
        'Flags' => [
          'key' => 'value',
        ],
      ],
      1 => [
        'CampaignId' => 'xxxxxxxxxxxxxxxxxxxx',
        'VariationGroupId' => 'xxxxxxxxxxxxxxxxxxxx',
        'VariationId' => 'xxxxxxxxxxxxxxxxxxxx',
        'IsReference' => false,
        'Type' => '',
        'Activated' => false,
        'Flags' => [
          'myAwesomeFeature' => 20,
        ],
      ],
    ],
  ],
]
```

**Example**

```php
<?php

require_once __DIR__ . '/vendor/autoload.php';


use Flagship\Cache\IVisitorCacheImplementation;
use Flagship\Config\FlagshipConfig;
use Flagship\Flagship;


/**
 * Implementing visitor caches with redis
 */
class VisitorCacheRedis implements IVisitorCacheImplementation{

    private $redis;
    public function __construct($address, $port)
    {
        $this->redis = new Redis();
        $this->redis->connect($address, $port);
    }

    public function cacheVisitor($visitorId, array $data)
    {
        $this->redis->set($visitorId, json_encode($data, JSON_NUMERIC_CHECK));
    }

    public function lookupVisitor($visitorId)
    {
        $data = $this->redis->get($visitorId);
        if (!$data){
            return null;
        }
        return json_decode($data, true);
    }

    public function flushVisitor($visitorId)
    {
      $this->redis->del($visitorId);
    }
}

Flagship::start("your_env_id", "your_api_key",
    FlagshipConfig::bucketing("http://127.0.0.1:8080/bucketing") // set the sync-agent endpoint URL
    ->setVisitorCacheImplementation(new VisitorCacheRedis("127.0.0.1", 6379)) // set visitor cache implementation 
);

$visitor = Flagship::newVisitor("visitorID")
        ->withContext(["plan"=>"enterprise"])
        ->build();

$visitor->fetchFlags();

$flag = $visitor->getFlag("your_flag_key", "default_value") ;
echo "value: ". $flag->getValue()."\n";
echo "exists: ". $flag->exists()."\n";
echo "metadata: ". json_encode($flag->getMetadata());
```

#### Hit Cache

The hit cache is used to store hits in your database depending on strategy used through the `IHitCacheImplementation` interface which defines the methods that an object must implement to handle it.

```php
interface IHitCacheImplementation
{
    public function cacheHit(array $hits):void;

    public function lookupHits():array;

    public function flushHits(array $hitKeys):void;

    public function flushAllHits():void;
}
```

\\

**`cacheHit` function**

This method will be called to cache hits depending on cache strategy used.

* **`public function cacheHit(array $hits):void`**

It has 1 argument :

```
  <td style={{ textAlign: "left" }}>
    array
  </td>

  <td style={{ textAlign: "left" }}>
    it's an associative array where the :  

    * key  is a unique ID for each hit  
    * value is an array that follows the shape of type [`HitCacheDTO`](#hitCachedto).
  </td>
</tr>
```

<table data-header-hidden><thead><tr><th></th></tr></thead><tbody><tr><td><pre><code>  &#x3C;/th>
&#x3C;th style={{ textAlign: "left" }}>
&#x3C;/th>
&#x3C;th style={{ textAlign: "left" }}>
&#x3C;/th>
&#x3C;/tr>
</code></pre></td></tr><tr><td>hits</td></tr></tbody></table>

\\

**`lookupHits` function**

This method will be called to load all hits from your database and trying to send them again when `Flagship::close()`.

It has to return an associative array where the key is a unique ID for each hit and the value is an array which follows this shape [see](#hitCachedto).

* **`public function lookupHits():array`**

\\

**`flushHits` function**

This method will be called to erase all hits matching the unique Hits ID from your database.

**NOTE:** It will be called every time [`setConsent`](#setconsent-function) get false to erase all hits from database for visitor who set consent to false.

* **`public function flushHits(array $hitKeys):void`**

It has one argument :

| Argument | Type           | Description       |
| -------- | -------------- | ----------------- |
| hitKeys  | Array\<string> | Unique ID of hits |

\\

**`flushAllHits` function**

This method will be called to erase all hits in your database without exception.

* **`public function flushAllHits():void`**

\\

**HitCacheDTO**

```php
[
    'visitorId:Guid' => [
        'version' => 1,
        'data' => [
            'visitorId' => 'visitorId',
            'anonymousId' => NULL,
            'type' => 'ACTIVATE',
            'content' => [
                'variationGroupId' => 'xxxxxxxxxxxxxxx',
                'variationId' => 'xxxxxxxxxxxxxxxx',
                'visitorId' => 'visitorId',
                'ds' => 'APP',
                'type' => 'ACTIVATE',
                'anonymousId' => NULL,
                'userIP' => NULL,
                'pageResolution' => NULL,
                'locale' => NULL,
                'sessionNumber' => NULL,
                'key' => 'visitorId:Guid',
                'createdAt' => 1676542078044,
            ],
            'time' => 1676542078045,
        ],
    ]
]
```

> 📘
>
> * `flushHits` method will be called every time [`setConsent`](#setconsent-function) get false.
> * `Hits` older than 4H will be ignored during the resending process.

\\

Sample implementation of IHitCacheImplementation interface using redis

```php
use Flagship\Cache\IHitCacheImplementation;

class HitCacheRedis implements IHitCacheImplementation
{

    private $redis;
    public function __construct($address, $port, $dbIndex)
    {
        $this->redis = new Redis();
        $this->redis->connect($address, $port);
        $this->redis->select($dbIndex);
    }

    /**
     * @inheritDoc
     */
    public function cacheHit(array $hits)
    {
        $redis = $this->redis->multi();
        foreach ($hits as $key => $hit) {
            $redis->set($key, json_encode($hit));
        }
        $redis->exec();
    }

    /**
     * @inheritDoc
     */
    public function lookupHits()
    {
        $keys = $this->redis->keys('*');
        $hits = $this->redis->mGet($keys);
        if (!$hits) {
            return [];
        }
        $hitsOut = [];
        foreach ($hits as $key => $hit) {
            $hitsOut[$keys[$key]] = json_decode($hit, true);
        }
        return $hitsOut;
    }

    /**
     * @inheritDoc
     */
    public function flushHits(array $hitKeys)
    {
        $this->redis->del($hitKeys);
    }

    public function flushAllHits()
    {
        $this->redis->flushDB();
    }
}
```

\\

### API reference

#### `Flagship` class

* [start](#initialization)
* [newVisitor](#create-a-new-visitor)
* [close](#close-function)
* [getStatus](#getstatus-function)
* [getConfig](#getconfig-function)

#### `Visitor` class

* [updateContext](#updating-the-visitor-context)
* [context](#updating-the-visitor-context)
* [clearContext](#updating-the-visitor-context)
* [fetchFlags](#fetching-flags)
* [getFlag](#getflag-function)
* [setConsent](#managing-visitor-consent)
* [hasConsented](#managing-visitor-consent)
* [Authenticate](#authenticate)
* [Unauthenticate](#unauthenticate)
* [sendHit](#hit-tracking)

#### `Flag` class

* [getValue](#getvalue-function)
* [getMetadata](#getmetadata-function)
* [visitorExposed](#visitorexposed-function)
* [exists](#exists-function)

### Appendix

#### Predefined visitor context keys

The Flagship SDK contains predefined visitor context keys.

The keys marked as **Yes** in the **Auto-set by SDK** column will be automatically set, while the ones marked as **No** need to be set by customer.

You can overwrite these keys at any time. The key-value pairs will be sent to the server in the visitor context and can be edited in the [Persona](doc:glossary#persona) section of the Flagship platform.

> 📘
>
> To overwrite the keys, use the [`updateContext`](#update-context-with-predefined-keys-of-context) method

| SDK constant Name                     | Description                                            | Context variable name   | Type       | Auto-set by SDK | Example         |
| ------------------------------------- | ------------------------------------------------------ | ----------------------- | ---------- | --------------- | --------------- |
| FlagshipContext::DEVICE\_LOCALE       | Language of the device                                 | sdk\_deviceLanguage     | String     | No              | fra             |
| FlagshipContext::DEVICE\_TYPE         | Type of the device                                     | sdk\_deviceType         | DeviceType | No              | Mobile          |
| FlagshipContext::DEVICE\_MODEL        | Model of the device                                    | sdk\_deviceModel        | String     | No              | samsung E1200   |
| FlagshipContext::LOCATION\_CITY       | City geolocation                                       | sdk\_city               | String     | No              | toulouse        |
| FlagshipContext::LOCATION\_REGION     | Region geolocation                                     | sdk\_region             | String     | No              | occitanie       |
| FlagshipContext::LOCATION\_COUNTRY    | Country geolocation                                    | sdk\_country            | String     | No              | France          |
| FlagshipContext::LOCATION\_LAT        | Current Latitude                                       | sdk\_lat                | Double     | No              | 43.623647       |
| FlagshipContext::LOCATION\_LONG       | Current Longitude                                      | sdk\_long               | Double     | No              | 1.445397        |
| FlagshipContext::IP                   | IP of the device                                       | sdk\_ip                 | String     | No              | 127.0.0.1       |
| FlagshipContext::OS\_NAME             | Name of the OS                                         | sdk\_osName             | String     | YES             | ubuntu / centos |
| FlagshipContext::OS\_VERSION\_NAME    | Version name of the OS                                 | sdk\_osVersionName      | String     | No              | 9.0.0           |
| FlagshipContext::OS\_VERSION\_CODE    | Version code of the OS                                 | sdk\_osVersionCode      | Number     | No              | 24              |
| FlagshipContext::CARRIER\_NAME        | Name of the carrier or mobile virtual network operator | sdk\_carrierName        | String     | No              | free            |
| FlagshipContext::INTERNET\_CONNECTION | What is the internet connection                        | sdk\_internetConnection | String     | No              | 5g              |
| FlagshipContext::APP\_VERSION\_NAME   | Version name of the app                                | sdk\_versionName        | String     | No              | 1.1.2-beta      |
| FlagshipContext::APP\_VERSION\_CODE   | Version code of the app                                | sdk\_versionCode        | Number     | No              | 40              |
| FlagshipContext::INTERFACE\_NAME      | Name of the interface                                  | sdk\_interfaceName      | String     | No              | ProductPage     |
| FlagshipContext::FLAGSHIP\_CLIENT     | Flagship SDK client (Reserved)                         | fs\_client              | String     | Yes             | PHP             |
| FlagshipContext::FLAGSHIP\_VERSION    | Version of the Flagship SDK (Reserved)                 | fs\_version             | String     | Yes             | 2.0.0           |
