* @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ namespace PrestaShop\Module\PsAccounts\Service; use PrestaShop\Module\PsAccounts\Vendor\Monolog\Logger; use PrestaShop\Module\PsAccounts\Vendor\Ramsey\Uuid\Uuid; use Segment; class AnalyticsService { const COOKIE_ANONYMOUS_ID = 'ajs_anonymous_id'; /** * @var Logger */ private $logger; /** * @var string|null */ private static $anonymousId; /** * @param string $segmentWriteKey * @param Logger $logger * * @throws \Exception */ public function __construct($segmentWriteKey, Logger $logger) { Segment::init($segmentWriteKey); $this->logger = $logger; $this->initAnonymousId(); } /** * @param array $message * * @return void */ public function track($message) { try { Segment::track($message); Segment::flush(); } catch (\Exception $e) { $this->logger->error($e->getMessage(), $message); } } /** * @param string|null $userUid * @param string $application * * @return void * * @throws \Exception */ public function trackUserSignedIntoApp($userUid, $application) { $this->track([ 'event' => 'User Signed Into App', 'userId' => $userUid, 'anonymousId' => $this->getAnonymousId(), 'properties' => [ 'application' => $application, ], ]); } /** * @param string|null $userUid * @param string $userEmail * * @return void * * @throws \Exception */ public function trackUserSignedIntoBackOfficeLocally($userUid, $userEmail) { $this->track([ 'event' => 'User Signed Into Back Office Locally', 'userId' => $userUid, 'anonymousId' => $this->getAnonymousId(), 'properties' => [ 'email' => $userEmail, ], ]); } /** * @param string|null $userUid * @param string|null $type * @param string|null $description * * @return void * * @throws \Exception */ public function trackBackOfficeSSOSignInFailed($userUid, $type, $description) { $this->track([ 'event' => 'Back Office SSO Sign In Failed', 'userId' => $userUid, 'anonymousId' => $this->getAnonymousId(), 'properties' => [ 'type' => $type, 'description' => $description, ], ]); } /** * @param string|null $userUid * @param string $userEmail * @param string $shopUid * @param string $shopUrl * @param string $shopBoUrl * @param string|null $triggeredBy * @param string|null $errorCode * * @return void * * @throws \Exception */ public function trackShopUnlinkedOnError( $userUid, $userEmail, $shopUid, $shopUrl, $shopBoUrl, $triggeredBy = null, $errorCode = null ) { $this->track([ 'event' => 'Unintentionally Dissociated', 'userId' => $userUid, 'anonymousId' => $this->getAnonymousId(), 'properties' => [ 'shopUid' => $shopUid, 'shopUrl' => $shopUrl, 'shopBoUrl' => $shopBoUrl, 'ownerEmail' => $userEmail, 'dissociatedAt' => (new \DateTime())->format('Uv'), 'psStoreVersion' => _PS_VERSION_, 'psAccountVersion' => \Ps_accounts::VERSION, 'triggeredBy' => $triggeredBy, 'errorCode' => $errorCode, ], ]); } /** * @param string $name * @param string|null $userId * @param string|null $path * @param string|null $referrer * @param string|null $search * @param string|null $title * @param string|null $url * * @return void * * @throws \Exception */ public function page( $name, $userId = null, $path = null, $referrer = null, $search = null, $title = null, $url = null ) { $message = [ 'userId' => $userId, 'anonymousId' => $this->getAnonymousId(), 'name' => $name, 'properties' => [ 'path' => $path !== null ? $path : $_SERVER['PATH_INFO'], 'referrer' => $referrer !== null ? $referrer : $_SERVER['HTTP_REFERER'], 'search' => $search, 'title' => $title, 'url' => $url !== null ? $url : $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], ], ]; try { Segment::page($message); Segment::flush(); } catch (\Exception $e) { $this->logger->error($e->getMessage(), $message); } } /** * @param string|null $userUid * * @return void * * @throws \Exception */ public function pageAccountsBoLogin($userUid = null) { $this->page('Accounts Backoffice Login Page', $userUid); } /** * @param string|null $userUid * * @return void * * @throws \Exception */ public function pageLocalBoLogin($userUid = null) { $this->page('Local Backoffice Login Page', $userUid); } /** * @param string|null $userUid * @param string|null $name * @param string|null $email * * @return void * * @throws \Exception */ public function identify($userUid, $name, $email) { $message = [ 'userId' => $userUid, 'anonymousId' => $this->getAnonymousId(), 'traits' => [$name ? ['name' => $name] : []] + [$email ? ['email' => $email] : []], ]; try { Segment::identify($message); } catch (\Exception $e) { $this->logger->error($e->getMessage(), $message); } } /** * @param string|null $userUid * @param string $shopUid * * @return void * * @throws \Exception */ public function group($userUid, $shopUid) { $message = [ 'userId' => $userUid, 'groupId' => $shopUid, 'anonymousId' => $this->getAnonymousId(), // "traits" => [ // "name" => $shopName, // ] ]; try { Segment::group($message); } catch (\Exception $e) { $this->logger->error($e->getMessage(), $message); } } /** * @return string * * @throws \Exception */ public function getAnonymousId() { $this->initAnonymousId(); return self::$anonymousId; } /** * @return void * * @throws \Exception */ private function initAnonymousId() { if (!isset(self::$anonymousId)) { if (!isset($_COOKIE[self::COOKIE_ANONYMOUS_ID])) { self::$anonymousId = Uuid::uuid4()->toString(); try { setcookie(self::COOKIE_ANONYMOUS_ID, self::$anonymousId, time() + 3600); } catch (\Exception $e) { $this->logger->error($e->getMessage()); } } else { self::$anonymousId = $_COOKIE[self::COOKIE_ANONYMOUS_ID]; } } } }