<?php declare(strict_types=1);
namespace Cbax\ModulAnalytics\Subscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Product\Events\ProductSearchResultEvent;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Cbax\ModulAnalytics\Components\ConfigReaderHelper;
use Shopware\Core\Defaults;
use Shopware\Core\Checkout\Order\OrderDefinition;
use Shopware\Core\Checkout\Order\OrderEvents;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
class BackendSubscriber implements EventSubscriberInterface
{
/**
* @var ConfigReaderHelper
*/
private $config;
/**
* @var EntityRepositoryInterface
*/
private $searchRepository;
/**
* @var EntityRepositoryInterface
*/
private $orderRepository;
const DEFAULT_DEVICES = [
'desktop',
'tablet',
'mobile'
];
public function __construct(
ConfigReaderHelper $config,
EntityRepositoryInterface $searchRepository,
EntityRepositoryInterface $orderRepository
)
{
$this->config = $config->getConfig();
$this->orderRepository = $orderRepository;
$this->searchRepository = $searchRepository;
}
public static function getSubscribedEvents(): array
{
return[
ProductSearchResultEvent::class => 'onProductSearch',
OrderEvents::ORDER_WRITTEN_EVENT => 'onOrderWritten',
];
}
public function onOrderWritten(EntityWrittenEvent $event)
{
if (empty($_SERVER)) return;
if (empty($_SERVER['HTTP_USER_AGENT'])) return;
if ($event->getEntityName() !== OrderDefinition::ENTITY_NAME) return;
$httpUserAgent = $_SERVER['HTTP_USER_AGENT'];
$context = $event->getContext();
foreach ($event->getWriteResults() as $writeResult) {
if ($writeResult->getExistence() !== null && $writeResult->getExistence()->exists()) continue;
if ($writeResult->getOperation() !== 'insert') continue;
$payload = $writeResult->getPayload();
if (empty($payload)) continue;
$customFields = !empty($payload['customFields']) ? $payload['customFields'] : [];
if (empty($payload['versionId'])) continue;
if ($payload['versionId'] !== Defaults::LIVE_VERSION) continue;
if (!empty($customFields) && !empty($customFields['cbaxExternalOrderOrdernumber'])) continue;
$customFields['cbaxStatistics'] = [
'device' => $this->getDeviceType($httpUserAgent),
'os' => $this->getOS($httpUserAgent),
'browser' => $this->getBrowser($httpUserAgent)
];
$data = [
[
'id' => $payload['id'],
'customFields' => $customFields
]
];
$this->orderRepository->update($data, $context);
}
}
public function onProductSearch(ProductSearchResultEvent $event)
{
if (empty($this->config['recordSearch'])) return;
$requestUri = $event->getRequest()->attributes->get('sw-original-request-uri');
if (empty($requestUri)) return;
if (str_starts_with($requestUri, '/widgets')) return;
$searchUriArray = explode('=', $requestUri);
$searchTerm = count($searchUriArray) > 1 ? strtolower(urldecode ($searchUriArray[1])) : '';
if (empty($searchTerm)) return;
$results = $event->getResult()->getTotal();
$context = $event->getContext();
$salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
$this->searchRepository->create([
[
'searchTerm' => $searchTerm,
'results' => $results,
'salesChannelId' => $salesChannelId
]
], $context);
}
private function getDeviceType($httpUserAgent)
{
if (!empty($_COOKIE) && !empty($_COOKIE['x-ua-device']))
{
$deviceType = strtolower($_COOKIE['x-ua-device']);
if (in_array($deviceType, self::DEFAULT_DEVICES))
{
return $deviceType;
}
}
$os = $this->getOS($httpUserAgent);
$mobileOS = ['Windows Phone 10','Windows Phone 8.1','Windows Phone 8','BlackBerry','Mobile'];
if (preg_match('/mobile|phone|ipod/i', $httpUserAgent) || in_array($os, $mobileOS))
{
return 'mobile';
}
$tabletOS = ['Android','iOS'];
if (preg_match('/tablet|ipad/i', $httpUserAgent) || in_array($os, $tabletOS))
{
return 'tablet';
}
return 'desktop';
}
private function getOS($httpUserAgent)
{
foreach (self::OS as $key => $value) {
if (preg_match($key, $httpUserAgent)) {
return $value;
}
}
return 'Not Detected';
}
private function getBrowser($httpUserAgent)
{
foreach (self::BROWSER as $key => $value) {
if (preg_match($key, $httpUserAgent)) {
return $value;
}
}
return 'Not Detected';
}
const OS = [
'/windows nt 10/i' => 'Windows 10',
'/windows phone 10/i' => 'Windows Phone 10',
'/windows phone 8.1/i' => 'Windows Phone 8.1',
'/windows phone 8/i' => 'Windows Phone 8',
'/windows nt 6.3/i' => 'Windows 8.1',
'/windows nt 6.2/i' => 'Windows 8',
'/windows nt 6.1/i' => 'Windows 7',
'/windows nt 6.0/i' => 'Windows Vista',
'/windows nt 5.2/i' => 'Windows Server 2003/XP x64',
'/windows nt 5.1/i' => 'Windows XP',
'/windows xp/i' => 'Windows XP',
'/windows nt 5.0/i' => 'Windows 2000',
'/windows me/i' => 'Windows ME',
'/win98/i' => 'Windows 98',
'/win95/i' => 'Windows 95',
'/win16/i' => 'Windows 3.11',
'/macintosh|mac os x/i' => 'Mac OS X',
'/mac_powerpc/i' => 'Mac OS 9',
'/iphone/i' => 'iOS',
'/ipod/i' => 'iOS',
'/ipad/i' => 'iOS',
'/android/i' => 'Android',
'/linux/i' => 'Linux',
'/ubuntu/i' => 'Ubuntu',
'/blackberry/i' => 'BlackBerry',
'/webos/i' => 'Mobile'
];
const BROWSER = [
'/firefox/i' => 'Firefox',
'/msie/i' => 'Internet Explorer',
'/edge/i' => 'Edge',
'/edg/i' => 'Edge',
'/opera/i' => 'Opera',
'/chrome/i' => 'Chrome',
'/safari/i' => 'Safari',
'/mobile/i' => 'Handheld Browser',
'/netscape/i' => 'Netscape',
'/maxthon/i' => 'Maxthon',
'/konqueror/i' => 'Konqueror'
];
}