Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tracker\Service\ContactTrackingService;
|
||||
|
||||
use Mautic\CoreBundle\Helper\CookieHelper;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Entity\LeadDeviceRepository;
|
||||
use Mautic\LeadBundle\Entity\LeadRepository;
|
||||
use Mautic\LeadBundle\Entity\MergeRecordRepository;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
/**
|
||||
* Used to ensure that contacts tracked under the old method are continued to be tracked under the new.
|
||||
*/
|
||||
final class ContactTrackingService implements ContactTrackingServiceInterface
|
||||
{
|
||||
public function __construct(
|
||||
private CookieHelper $cookieHelper,
|
||||
private LeadDeviceRepository $leadDeviceRepository,
|
||||
private LeadRepository $leadRepository,
|
||||
private MergeRecordRepository $mergeRecordRepository,
|
||||
private RequestStack $requestStack,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Lead|null
|
||||
*/
|
||||
public function getTrackedLead()
|
||||
{
|
||||
$request = $this->requestStack->getCurrentRequest();
|
||||
|
||||
if (null === $request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$trackingId = $this->getTrackedIdentifier();
|
||||
if (null === $trackingId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$leadId = $this->cookieHelper->getCookie($trackingId, null);
|
||||
if (null === $leadId) {
|
||||
$leadId = $request->get('mtc_id', null);
|
||||
if (null === $leadId) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$lead = $this->leadRepository->getEntity($leadId);
|
||||
if (null === $lead) {
|
||||
// Check if this contact was merged into another and if so, return the new contact
|
||||
$lead = $this->mergeRecordRepository->findMergedContact($leadId);
|
||||
|
||||
if (null === $lead) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Hydrate fields with custom field data
|
||||
$fields = $this->leadRepository->getFieldValues($lead->getId());
|
||||
$lead->setFields($fields);
|
||||
}
|
||||
|
||||
$anotherDeviceAlreadyTracked = $this->leadDeviceRepository->isAnyLeadDeviceTracked($lead);
|
||||
|
||||
return $anotherDeviceAlreadyTracked ? null : $lead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getTrackedIdentifier()
|
||||
{
|
||||
return $this->cookieHelper->getCookie('mautic_session_id', null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tracker\Service\ContactTrackingService;
|
||||
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
|
||||
/**
|
||||
* Interface ContactTrackingInterface.
|
||||
*/
|
||||
interface ContactTrackingServiceInterface
|
||||
{
|
||||
/**
|
||||
* Return current tracked Lead.
|
||||
*
|
||||
* @return Lead|null
|
||||
*/
|
||||
public function getTrackedLead();
|
||||
|
||||
/**
|
||||
* @return string|null Unique identifier
|
||||
*/
|
||||
public function getTrackedIdentifier();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tracker\Service\DeviceCreatorService;
|
||||
|
||||
use DeviceDetector\DeviceDetector;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Entity\LeadDevice;
|
||||
|
||||
final class DeviceCreatorService implements DeviceCreatorServiceInterface
|
||||
{
|
||||
public function getCurrentFromDetector(DeviceDetector $deviceDetector, Lead $assignedLead): LeadDevice
|
||||
{
|
||||
$device = new LeadDevice();
|
||||
$device->setClientInfo($deviceDetector->getClient());
|
||||
$device->setDevice($deviceDetector->getDeviceName());
|
||||
$device->setDeviceBrand($deviceDetector->getBrandName());
|
||||
$device->setDeviceModel($deviceDetector->getModel());
|
||||
$device->setDeviceOs($deviceDetector->getOs());
|
||||
$device->setDateAdded(new \DateTime());
|
||||
$device->setLead($assignedLead);
|
||||
|
||||
return $device;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tracker\Service\DeviceCreatorService;
|
||||
|
||||
use DeviceDetector\DeviceDetector;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
use Mautic\LeadBundle\Entity\LeadDevice;
|
||||
|
||||
/**
|
||||
* Interface DeviceCreatorServiceInterface.
|
||||
*/
|
||||
interface DeviceCreatorServiceInterface
|
||||
{
|
||||
/**
|
||||
* @return LeadDevice|null Null is returned if device can't be detected
|
||||
*/
|
||||
public function getCurrentFromDetector(DeviceDetector $deviceDetector, Lead $assignedLead);
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tracker\Service\DeviceTrackingService;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Mautic\CoreBundle\Helper\CookieHelper;
|
||||
use Mautic\CoreBundle\Helper\RandomHelper\RandomHelperInterface;
|
||||
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
|
||||
use Mautic\LeadBundle\Entity\LeadDevice;
|
||||
use Mautic\LeadBundle\Entity\LeadDeviceRepository;
|
||||
use Symfony\Component\HttpFoundation\Cookie;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
|
||||
final class DeviceTrackingService implements DeviceTrackingServiceInterface
|
||||
{
|
||||
private ?LeadDevice $trackedDevice = null;
|
||||
|
||||
public function __construct(
|
||||
private CookieHelper $cookieHelper,
|
||||
private EntityManagerInterface $entityManager,
|
||||
private LeadDeviceRepository $leadDeviceRepository,
|
||||
private RandomHelperInterface $randomHelper,
|
||||
private RequestStack $requestStack,
|
||||
private CorePermissions $security,
|
||||
) {
|
||||
}
|
||||
|
||||
public function isTracked(): bool
|
||||
{
|
||||
return null !== $this->getTrackedDevice();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?LeadDevice
|
||||
*/
|
||||
public function getTrackedDevice()
|
||||
{
|
||||
if (!$this->security->isAnonymous()) {
|
||||
// Do not track Mautic users
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->trackedDevice) {
|
||||
return $this->trackedDevice;
|
||||
}
|
||||
|
||||
$trackingId = $this->getTrackedIdentifier();
|
||||
if (null === $trackingId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->leadDeviceRepository->getByTrackingId($trackingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $replaceExistingTracking
|
||||
*
|
||||
* @return LeadDevice
|
||||
*/
|
||||
public function trackCurrentDevice(LeadDevice $device, $replaceExistingTracking = false)
|
||||
{
|
||||
$trackedDevice = $this->getTrackedDevice();
|
||||
if (null !== $trackedDevice && false === $replaceExistingTracking) {
|
||||
return $trackedDevice;
|
||||
}
|
||||
|
||||
if (null !== $existingDevice = $this->leadDeviceRepository->findExistingDevice($device)) {
|
||||
$device = $existingDevice;
|
||||
}
|
||||
|
||||
if (empty($device->getTrackingId())) {
|
||||
// Ensure all devices have a tracking ID (new devices will not and pre 2.13.0 devices may not)
|
||||
$device->setTrackingId($this->getUniqueTrackingIdentifier());
|
||||
|
||||
$this->entityManager->persist($device);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
$this->createTrackingCookies($device);
|
||||
|
||||
// Store the device in case a service uses this within the same session
|
||||
$this->trackedDevice = $device;
|
||||
|
||||
return $device;
|
||||
}
|
||||
|
||||
public function clearTrackingCookies(): void
|
||||
{
|
||||
$this->cookieHelper->deleteCookie('mautic_device_id');
|
||||
$this->cookieHelper->deleteCookie('mtc_id');
|
||||
}
|
||||
|
||||
private function getTrackedIdentifier(): ?string
|
||||
{
|
||||
$request = $this->requestStack->getCurrentRequest();
|
||||
|
||||
if (null === $request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->trackedDevice) {
|
||||
// Use the device tracked in case the cookies were just created
|
||||
return $this->trackedDevice->getTrackingId();
|
||||
}
|
||||
|
||||
$deviceTrackingId = $this->cookieHelper->getCookie('mautic_device_id', null);
|
||||
if (null === $deviceTrackingId) {
|
||||
$deviceTrackingId = $request->get('mautic_device_id', null);
|
||||
}
|
||||
|
||||
return $deviceTrackingId;
|
||||
}
|
||||
|
||||
private function getUniqueTrackingIdentifier(): string
|
||||
{
|
||||
do {
|
||||
$generatedIdentifier = $this->randomHelper->generate(23);
|
||||
$device = $this->leadDeviceRepository->getByTrackingId($generatedIdentifier);
|
||||
} while (null !== $device);
|
||||
|
||||
return $generatedIdentifier;
|
||||
}
|
||||
|
||||
private function createTrackingCookies(LeadDevice $device): void
|
||||
{
|
||||
// Device cookie
|
||||
$this->cookieHelper->setCookie('mautic_device_id', $device->getTrackingId(), 31_536_000, sameSite: Cookie::SAMESITE_NONE);
|
||||
|
||||
// Mainly for landing pages so that JS has the same access as 3rd party tracking code
|
||||
$this->cookieHelper->setCookie('mtc_id', $device->getLead()->getId(), null, sameSite: Cookie::SAMESITE_NONE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\LeadBundle\Tracker\Service\DeviceTrackingService;
|
||||
|
||||
use Mautic\LeadBundle\Entity\LeadDevice;
|
||||
|
||||
/**
|
||||
* Interface DeviceTrackingServiceInterface.
|
||||
*/
|
||||
interface DeviceTrackingServiceInterface
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isTracked();
|
||||
|
||||
/**
|
||||
* @return LeadDevice|null
|
||||
*/
|
||||
public function getTrackedDevice();
|
||||
|
||||
/**
|
||||
* @param bool $replaceExistingTracking
|
||||
*
|
||||
* @return LeadDevice
|
||||
*/
|
||||
public function trackCurrentDevice(LeadDevice $device, $replaceExistingTracking = false);
|
||||
|
||||
public function clearTrackingCookies();
|
||||
}
|
||||
Reference in New Issue
Block a user