setDebugHash($dbCfg['analytics']['google_tag_manager']['debugHash'] ?? false); $this->setServerUrl($dbCfg['analytics']['google_tag_manager']['serverUrl'] ?? false); } public function setDebugHash($hash) { $this->debugHash = $hash; } public function setServerUrl($url) { $this->serverUrl = $url; } public static function getContainerConfigPath(): ?string { global $cfg; $hasUrl = $cfg['Addr']['print'] ?? null; if (findModule(\Modules::GTM, \Modules::SUB_CONTAINER_CONFIG) && $hasUrl) { return substr($cfg['Addr']['print'], 0, -1).AbstractServerSideGTMEvent::ContainerConfigPath; } return null; } public function getServerUrl(): string { $dbcfg = \Settings::getDefault(); if ( (($dbcfg['analytics']['google_tag_manager']['container_config_ss'] ?? false) === 'Y') && ($domain = self::getContainerConfigPath()) ) { return $domain; } return $this->serverUrl; } public function start(Event $event) { $serverUrl = $this->getServerUrl(); if (!$serverUrl) { return; } $payload = $this->getPayload($event); $payloadJson = json_encode($payload); // Protože skripty v údržbě končí exit(), tím pádem se tam neprovede async handling // A takovej divnej if proto, abysme si byli jisti ze to je udrzba, resp. ze to dela superadmin if (isAdministration() && isSuperuser()) { $this->sendData($serverUrl, $payloadJson, $this->getHeader()); } else { $this->sendDataAsync($serverUrl, $payloadJson); } $this->logger->notice('[GTM-SS] Purchase payload', $payload); } public function setRequest(?Request $request) { $this->request = $request; } abstract protected function getPayload(Event $event): array; final protected function sendDataAsync(string $url, string $payload) { $headers = $this->getHeader(); $this->asyncQueue->addHandler(fn () => $this->sendData($url, $payload, $headers), '[GTM-SS] measure event'); } protected function sendData(string $url, string $payload, ?array $headers = null): void { $headers ??= $this->getHeader(); if ($this->debugHash) { $headers[] = 'x-gtm-server-preview: '.$this->debugHash; } $ch = curl_init('https://'.$url.'/measure'); // example: https://m.shop.wpj.cz/measure curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_exec($ch); curl_close($ch); } /** * @return string[] */ public function getHeader(): array { return [ 'Content-Type: application/json', "Cookie: _fbp={$this->getBrowserFBPixelSessionId($this->getRequest())}", ]; } protected function getCommonData(Event $event): array { $domain = $this->domainContext->getActiveId(); $request = $this->getRequest(); $referer = $request->headers->get('referer'); return [ 'client_id' => $this->getClientId(), 'user_id' => $this->getUserId(), 'ga_session_id' => $this->getBrowserGASessionId($request), 'ga_session_id_2' => $this->getBrowserGASessionId($request, '_2'), 'ga_session_id_3' => $this->getBrowserGASessionId($request, '_3'), 'currency' => $this->currencyContext->getActiveId(), 'language' => $this->languageContext->getActiveId(), 'page_encoding' => 'UTF-8', 'page_hostname' => $domain, 'page_location' => "https://{$domain}", 'ip_override' => $request->getClientIp(), 'page_path' => $referer, 'page_title' => null, 'page_referrer' => $referer, 'user_agent' => $request->headers->get('User-Agent'), 'user_data' => $this->getUserData($event), 'domain' => $domain, ]; } protected function getUserId(): string { return (string) \Cart::getCartID(false); } protected function getClientId(): string { return \Cart::getCartID(false).'_noCookie'; } protected function getUserData(Event $event): ?array { $prefixArray = []; if ($priceLevel = $this->priceLevelContext->getActive()) { $prefixArray['price_level'] = $priceLevel->name; } if ($event instanceof OrderEvent) { $order = $event->getOrder(); $user = $order->getUser(); $prefixArray += [ 'id' => $user instanceof \User ? (string) $user->id : null, 'groups' => is_array($user?->getGroups()) ? array_values(array_map(fn ($v) => $v['name'], $user->getGroups())) : null, ]; if ($admin = getAdminUser()) { $prefixArray['admin'] = $admin['login']; } $userStats = $this->fetchUsersStatsOrderData($order); return $prefixArray + [ 'lastOrderDate' => $userStats['last_date'] ?? null, 'firstOrderDate' => $userStats['first_date'] ?? null, 'countOrders' => $userStats['count'] ?? null, 'email_address' => $order->invoice_email, 'phone_number' => $order->invoice_phone, 'address' => [ 'first_name' => $order->invoice_name, 'last_name' => $order->invoice_surname, 'street' => $order->invoice_street, 'city' => $order->invoice_city, 'region' => $order->invoice_state, 'postal_code' => $order->invoice_zip, 'country' => $order->invoice_country, ], ]; } if ($user = $this->userContext->getActive()) { return $prefixArray + [ 'email_address' => $user->email ?? null, 'phone_number' => $user->phone ?? null, 'address' => [ 'first_name' => $user->name ?? null, 'last_name' => $user->surname ?? null, 'street' => $user->street ?? null, 'city' => $user->city ?? null, 'region' => $user->state ?? null, 'postal_code' => $user->zip ?? null, 'country' => $user->country ?? null, ], ]; } return null; } protected function getRequest(): ?Request { $request = $this->request ?? $this->requestStack->getMainRequest(); if (!$request && !isFrontend()) { $request = new Request(); } return $request; } }