Visitor Info
The VisitorInfo
is the central data object which is passed to every part of the targeting system. A new VisitorInfo
is created for every request and enriched with data throughout the matching process. Starting from an empty object, data
will be added to the VisitorInfo
from several components, making it hold all relevant targeting data for the current
request.
Visitor ID
To identify returning visitors, the engine needs some kind of unique identificator which will be assigned to each visitor.
This identificator, internally referred to as visitor ID
, is expected to be generated or set by the browser and to be
stored as a cookie. When creating a VisitorInfo
the targeting engine tries to load a visitor ID from the _pc_vis
cookie.
This ID is (by default) generated by the frontend on event:
- when loading a site with targeting enabled and no visitor ID was previously set, a random string is generated
If you want to manually set the visitor ID in your frontend code you can do so with the following call which is exposed by the targeting JS implementation:
_ptg.api.setVisitorId('my-custom-visitor-id');
The visitor ID will be used for every action where a unique identificator is needed, e.g. when identifying returning visitors or when persisting data for a specific visitor to a targeting storage.
Upon setting a visitor ID, it is stored in 2 places of the user's browser:
- a
_pc_vis
cookie - a
_ptg.user
local storage entry. This entry contains some persistent data about the user (e.g. an activity log and a list of previous visitor IDs) which may be used in later enhancements of the targeting framework. If the visitor ID cookie is missing but the local storage entry contains an ID that ID will be used to write a new cookie.
Accessing the Visitor Info in your code
Similar to the security token in Symfony's security system, you can fetch the current VisitorInfo
from a VisitorInfoStorage
.
This storage is defined as service an can simply be injected into your services or used as controller action argument when
your controllers are registered as service. You can just define the VisitorInfoStorageInterface
as dependency and Symfony
and the service configuration take care of the rest.
As an example, a sample service working with the VisitorInfo
:
<?php
namespace App\Targeting;
use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface;
class MyService
{
private VisitorInfoStorageInterface $visitorInfoStorage;
public function __construct(VisitorInfoStorageInterface $visitorInfoStorage)
{
$this->visitorInfoStorage = $visitorInfoStorage;
}
public function getVisitorId(): ?string
{
// always check if there is a visitor info before trying to fetch it
if (!$this->visitorInfoStorage->hasVisitorInfo()) {
return null;
}
$visitorInfo = $this->visitorInfoStorage->getVisitorInfo();
return $visitorInfo->getVisitorId();
}
}
And the matching service definition:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
# if using autowiring you're already set by just defining your service - the
# type hint against the VisitorInfoStorageInterface is enough to enable autowiring
App\Targeting\MyService: ~
# if you don't use autowiring you need to manually wire your dependency
App\Targeting\MyService:
arguments:
$visitorInfoStorage: '@Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface'
If your controllers are defined as services, you can make use of argument injection:
<?php
namespace App\Controller;
use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
class VisitorInfoController
{
/**
* @Route("/visitor-info")
*/
public function visitorInfoAction(VisitorInfoStorageInterface $visitorInfoStorage): JsonResponse
{
$data = [
'visitorId' => null
];
// always check if there is a visitor info before trying to fetch it
if ($visitorInfoStorage->hasVisitorInfo()) {
$visitorInfo = $visitorInfoStorage->getVisitorInfo();
$data['visitorId'] = $visitorInfo->getVisitorId();
}
return new JsonResponse($data);
}
}