<?php
namespace App\Manager\Webfactory;
use Container20kufZJ\getDoctrine_DatabaseDropCommandService;
use DateTime;
use JetBrains\PhpStorm\NoReturn;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
class StatistiquesManager
{
private string $urlAt;
private string $apiKey;
private string $beginDate;
private string $endDate;
public function __construct(private readonly SessionInterface $session, private readonly HttpClientInterface $httpClient, private readonly ParameterBagInterface $parameters, private readonly Security $security)
{
$this->urlAt = 'https://api.atinternet.io/v3/data/getData';
$this->beginDate = (new DateTime('first day of last month'))->format('Y-m-d'); // 1er jour du mois dernier
$this->endDate = (new DateTime('last day of last month'))->format('Y-m-d');// dernier jour du mois dernier
$this->apiKey = $this->parameters->get('api_atinternet_key');
}
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getAllStatistiques($pianoId, $advancedSats, $lang = 'FR', $magasin, $beginDate = null, $endDate = null): array
{
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$statsNbPagesVues = $this->getNbPagesVues($pianoId, $lang, $magasin, $dates['start'], $dates['end']);
$statsNbVisiteurs = $this->getNbVisiteurs($pianoId, $lang, $magasin, $dates['start'], $dates['end']);
$statsNbpagesVuesParVisites = $this->getNbPagesVuesParVisite($pianoId, $lang, $magasin, $dates['start'], $dates['end']);
$typeAppareils = $this->getTypesAppareils($pianoId, $lang, $magasin, $dates['start'], $dates['end']);
$typesSources = $this->getTraficSources($pianoId, $lang, $magasin, $dates['start'], $dates['end']);
$topPagesLastMonth = $this->getTopPagesVues($pianoId, $advancedSats, $lang, $magasin, $dates['start'], $dates['end']);
if ($advancedSats) {
// $topSecteurs = $this->getTraficCities($pianoId, $lang, $magasin, $dates['start'], $dates['end']);
$tempsMoyenSession = $this->getAverageLengthBySession($pianoId, $lang, $magasin, $dates['start'], $dates['end']);
$clicksCtas = $this->getAllCta($pianoId, $lang, $magasin, $dates['start'], $dates['end']);
$clicksSocialMedia = $this->getAllClicksSocialMedia($pianoId, $lang, $magasin, $dates['start'], $dates['end']);
return [
'pages_vues' => $statsNbPagesVues,
'visiteurs' => $statsNbVisiteurs,
'pages_vues_par_visites' => $statsNbpagesVuesParVisites,
'dureeSession' => $tempsMoyenSession,
// 'topSecteurs' => json_encode($topSecteurs),
'typesAppareils' => json_encode($typeAppareils),
'typesSources' => json_encode($typesSources),
'topPages' => $topPagesLastMonth,
'clicks_ctas' => $clicksCtas,
'clicks_socials' => $clicksSocialMedia
];
}
return [
'pages_vues' => $statsNbPagesVues,
'visiteurs' => $statsNbVisiteurs,
'pages_vues_par_visites' => $statsNbpagesVuesParVisites,
'typesAppareils' => json_encode($typeAppareils),
'typesSources' => json_encode($typesSources),
'topPages' => $topPagesLastMonth
];
}
/**
* Récupére le nombre de pages vues
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getNbPagesVues($pianoId, $lang, $magasin, $beginDate = null, $endDate = null)
{
$nbPagesVues = 0;
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$postDatas = [
'columns' => ['event_name', 'proprietary', 'lang_version', 'm_page_loads'],
'sort' => ['-m_page_loads'],
'filter' => [
'property' => [
'$AND' => [
[
'event_name' => [
'$eq' => 'page.display'
]
],
[
'proprietary' => [
'$eq' => $magasin
]
],
[
'lang_version' => [
'$eq' => $lang
]
]
]
]
],
'space' => ['s' => [intval($pianoId)]],
'period' => [
'p1' => [
[
'type' => 'D',
'start' => $dates['start'],
'end' => $dates['end']
]
]
],
'max-results' => 50,
'page-num' => 1,
'options' => ['ignore_null_properties' => true, 'eco_mode' => true]
];
$response = $this->getResponse($postDatas);
if ($response->getStatusCode() === 200) {
$datas = $response->toArray();
foreach ($datas['DataFeed']['Rows'] as $row) {
if ($row['event_name'] == 'page.display') {
$nbPagesVues = $row['m_page_loads'];
break;
}
}
}
return $nbPagesVues;
}
/**
* Récupére la durée moyenne d'une session
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getAverageLengthBySession($pianoId, $lang, $magasin, $beginDate = null, $endDate = null)
{
$dureeMoyenne = '0';
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$postDatas = [
'columns' => [
'event_name',
'proprietary',
'lang_version',
'm_time_spent_per_visits'
],
'sort' => [
'-m_time_spent_per_visits'
],
'filter' => [
'property' => [
'$AND' => [
[
'proprietary' => [
'$eq' => $magasin
]
],
[
'lang_version' => [
'$eq' => $lang
]
]
]
]
],
'space' => [
's' => [
intval($pianoId)
]
],
'period' => [
'p1' => [
[
'type' => 'D',
'start' => $dates['start'],
'end' => $dates['end']
]
]
],
'max-results' => 50,
'page-num' => 1,
'options' => [
'ignore_null_properties' => true,
'eco_mode' => true
]
];
$response = $this->getResponse($postDatas);
if ($response->getStatusCode() === 200) {
$datas = $response->toArray();
foreach ($datas['DataFeed']['Rows'] as $row) {
$dureeMoyenne += $row['m_time_spent_per_visits'];
}
}
if ($dureeMoyenne > 0) {
$datas = ['hours' => intval(gmdate('H', ($dureeMoyenne / 1000))), 'minutes' => intval(gmdate('i', ($dureeMoyenne / 1000))), 'secondes' => intval(gmdate('s', ($dureeMoyenne / 1000)))];
$dureeMoyenne = ($datas['hours'] > 0) ? $datas['hours'] . ' h ' : '';
$dureeMoyenne .= ($datas['minutes'] > 0) ? $datas['minutes'] . ' min ' : '';
$dureeMoyenne .= ($datas['secondes'] > 0) ? $datas['secondes'] . ' s' : '';
}
return $dureeMoyenne;
}
/**
* Récupére les différentes villes d'ou viennent le trafic
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getTraficCities($pianoId, $lang, $magasin, $beginDate = null, $endDate = null): array
{
$finalDatas = [];
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$postDatas = [
'columns' => [
'page',
'proprietary',
'lang_version',
'm_page_loads',
'geo_city',
'm_visits'
],
'sort' => [
'-m_page_loads'
],
'filter' => [
'property' => [
'$AND' => [
[
'proprietary' => [
'$eq' => $magasin
]
],
[
'lang_version' => [
'$eq' => $lang
]
]
]
]
],
'space' => [
's' => [
intval($pianoId)
]
],
'period' => [
'p1' => [
[
'type' => 'D',
'start' => $dates['start'],
'end' => $dates['end']
]
]
],
'max-results' => 4,
'page-num' => 1,
'options' => [
'ignore_null_properties' => true,
'eco_mode' => true
]
];
$response = $this->getResponse($postDatas);
if ($response->getStatusCode() === 200) {
$datas = $response->toArray();
foreach ($datas['DataFeed']['Rows'] as $row) {
$finalDatas[] = ['ville' => $row['geo_city'], 'visites' => $row['m_visits']];
}
}
return $finalDatas;
}
/**
* Récupére les types d'appareils utilisés (mobile, tablette, ..)
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getTypesAppareils($pianoId, $lang, $magasin, $beginDate = null, $endDate = null): array
{
$finalDatas = [];
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$postDatas = [
'columns' => [
'device_type',
'proprietary',
'lang_version',
'm_visits'
],
'sort' => [
'-m_visits'
],
'filter' => [
'property' => [
'$AND' => [
[
'proprietary' => [
'$eq' => $magasin
]
],
[
'lang_version' => [
'$eq' => $lang
]
]
]
]
],
'space' => [
's' => [
intval($pianoId)
]
],
'period' => [
'p1' => [
[
'type' => 'D',
'start' => $dates['start'],
'end' => $dates['end']
]
]
],
'max-results' => 50,
'page-num' => 1,
'options' => [
'ignore_null_properties' => true,
'eco_mode' => true
]
];
$response = $this->getResponse($postDatas);
if ($response->getStatusCode() === 200) {
$datas = $response->toArray();
foreach ($datas['DataFeed']['Rows'] as $row) {
$finalDatas[] = ['type' => $row['device_type'], 'visites' => $row['m_visits']];
}
}
return $finalDatas;
}
/**
* Récupére les sources de trafic ( réseaux sociaux, .. )
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getTraficSources($pianoId, $lang, $magasin, $beginDate = null, $endDate = null): array
{
$finalDatas = [];
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$postDatas = [
'columns' => [
'src',
'proprietary',
'lang_version',
'm_visits'
],
'sort' => [
'-m_visits'
],
'filter' => [
'property' => [
'$AND' => [
[
'proprietary' => [
'$eq' => $magasin
]
],
[
'lang_version' => [
'$eq' => $lang
]
]
]
]
],
'space' => [
's' => [
intval($pianoId)
]
],
'period' => [
'p1' => [
[
'type' => 'D',
'start' => $dates['start'],
'end' => $dates['end']
]
]
],
'max-results' => 50,
'page-num' => 1,
'options' => [
'ignore_null_properties' => true,
'eco_mode' => true
]
];
$response = $this->getResponse($postDatas);
$total = 0;
if ($response->getStatusCode() === 200) {
$datas = $response->toArray();
foreach ($datas['DataFeed']['Rows'] as $row) {
$finalDatas[] = ['type' => $row['src'], 'visites' => $row['m_visits']];
$total += $row['m_visits'];
}
}
foreach ($finalDatas as $key => $data) {
$finalDatas[$key]['pourcent'] = round((($data['visites'] / $total) * 100), 2);
}
return $finalDatas;
}
/**
* Récupére les pages les plus vues
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getTopPagesVues($pianoId, $advancedSats, $lang, $magasin, $beginDate = null, $endDate = null): array
{
$finalDatas = [];
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$postDatas = [
'columns' => [
'page',
'proprietary',
'lang_version',
'm_page_loads'
],
'sort' => [
'-m_page_loads'
],
'filter' => [
'property' => [
'$AND' => [
[
'page' => [
'$empty' => false
]
],
[
'proprietary' => [
'$eq' => $magasin
]
],
[
'lang_version' => [
'$eq' => $lang
]
]
]
]
],
'space' => [
's' => [
intval($pianoId)
]
],
'period' => [
'p1' => [
[
'type' => 'D',
'start' => $dates['start'],
'end' => $dates['end']
]
]
],
'max-results' => (($advancedSats) ? 10 : 3),
'page-num' => 1,
'options' => [
'ignore_null_properties' => true,
'eco_mode' => true
]
];
$response = $this->getResponse($postDatas);
if ($response->getStatusCode() === 200) {
$datas = $response->toArray();
foreach ($datas['DataFeed']['Rows'] as $row) {
$finalDatas[] = ['url' => $row['page'], 'visites' => $row['m_page_loads']];
}
}
return $finalDatas;
}
/**
* Récupére le nombre de visites
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getNbVisiteurs($pianoId, $lang, $magasin, $beginDate = null, $endDate = null)
{
$nbPagesVues = 0;
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$postDatas = [
'columns' => [
'event_name',
'lang_version',
'proprietary',
'm_unique_visitors'
],
'sort' => [
'-m_unique_visitors'
],
'filter' => [
'property' => [
'$AND' => [
[
'event_name' => [
'$eq' => 'page.display'
]
],
[
'lang_version' => [
'$eq' => $lang
]
],
[
'proprietary' => [
'$eq' => $magasin
]
]
]
]
],
'space' => [
's' => [
intval($pianoId)
]
],
'period' => [
'p1' => [
[
'type' => 'D',
'start' => $dates['start'],
'end' => $dates['end']
]
]
],
'max-results' => 50,
'page-num' => 1,
'options' => [
'ignore_null_properties' => true,
'eco_mode' => true
]
];
$response = $this->getResponse($postDatas);
if ($response->getStatusCode() === 200) {
$datas = $response->toArray();
foreach ($datas['DataFeed']['Rows'] as $row) {
if ($row['event_name'] == 'page.display') {
$nbPagesVues = $row['m_unique_visitors'];
break;
}
}
}
return $nbPagesVues;
}
/**
* Récupére la moyenne des pages vues par visite
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getNbPagesVuesParVisite($pianoId, $lang, $magasin, $beginDate = null, $endDate = null): float|int
{
$nbPagesVues = 0;
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$postDatas = [
'columns' => [
'event_name',
'proprietary',
'lang_version',
'm_page_loads_per_visit'
],
'sort' => [
'-m_page_loads_per_visit'
],
'filter' => [
'property' => [
'$AND' => [
[
'proprietary' => [
'$eq' => $magasin
]
],
[
'lang_version' => [
'$eq' => $lang
]
]
]
]
],
'space' => [
's' => [
intval($pianoId)
]
],
'period' => [
'p1' => [
[
'type' => 'D',
'start' => $dates['start'],
'end' => $dates['end']
]
]
],
'max-results' => 50,
'page-num' => 1,
'options' => [
'ignore_null_properties' => true,
'eco_mode' => true
]
];
$response = $this->getResponse($postDatas);
if ($response->getStatusCode() === 200) {
$datas = $response->toArray();
foreach ($datas['DataFeed']['Rows'] as $row) {
if ($row['event_name'] == 'page.display') {
$nbPagesVues = round($row['m_page_loads_per_visit']);
break;
}
}
}
return $nbPagesVues;
}
/**
* Récupére le nombre de clic sur les CTA Y aller, appeler, mail, prise de rdv
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getAllCta($pianoId, $lang, $magasin, $beginDate = null, $endDate = null): array
{
$finalDatas = [
'clicks_cta_phone' => 0,
'clicks_cta_mail' => 0,
'clicks_cta_rdv' => 0,
'clicks_cta_location' => 0,
];
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$postDatas = [
'columns' => [
'event_name',
'click',
'proprietary',
'lang_version',
'm_events'
],
'sort' => [
'-m_events'
],
'filter' => [
'property' => [
'$AND' => [
[
'event_name' => [
'$eq' => 'click.cta'
]
],
[
'proprietary' => [
'$eq' => $magasin
]
],
[
'lang_version' => [
'$eq' => $lang
]
]
]
]
],
'space' => [
's' => [
intval($pianoId)
]
],
'period' => [
'p1' => [
[
'type' => 'D',
'start' => $dates['start'],
'end' => $dates['end']
]
]
],
'max-results' => 50,
'page-num' => 1,
'options' => [
'ignore_null_properties' => true
]
];
$response = $this->getResponse($postDatas);
if ($response->getStatusCode() === 200) {
$datas = $response->toArray();
foreach ($datas['DataFeed']['Rows'] as $row) {
if ($row['event_name'] == 'click.cta') {
switch ($row['click']) {
case 'phone':
$finalDatas['clicks_cta_phone'] = $row['m_events'];
break;
case 'mail':
$finalDatas['clicks_cta_mail'] = $row['m_events'];
break;
case 'location':
$finalDatas['clicks_cta_location'] = $row['m_events'];
break;
case 'rdv':
$finalDatas['clicks_cta_rdv'] = $row['m_events'];
break;
}
}
}
}
return $finalDatas;
}
/**
* Récupére le nombre de clic sur les réseaux sociaux
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function getAllClicksSocialMedia($pianoId, $lang, $magasin, $beginDate = null, $endDate = null): int
{
$nbClicks = 0;
$dates = [
'start' => (!is_null($beginDate) ? $beginDate : $this->beginDate),
'end' => (!is_null($endDate) ? $endDate : $this->endDate)
];
$postDatas = [
'columns' => [
'event_name',
'click_chapter1',
'proprietary',
'lang_version',
'm_events'
],
'sort' => [
'-m_events'
],
'filter' => [
'property' => [
'$AND' => [
[
'click_chapter1' => [
'$eq' => 'social_networks'
]
],
[
'proprietary' => [
'$eq' => $magasin
]
],
[
'lang_version' => [
'$eq' => $lang
]
]
]
]
],
'space' => [
's' => [
intval($pianoId)
]
],
'period' => [
'p1' => [
[
'type' => 'D',
'start' => $dates['start'],
'end' => $dates['end']
]
]
],
'max-results' => 50,
'page-num' => 1,
'options' => [
'ignore_null_properties' => true
]
];
$response = $this->getResponse($postDatas);
if ($response->getStatusCode() === 200) {
$datas = $response->toArray();
foreach ($datas['DataFeed']['Rows'] as $row) {
$nbClicks = $row['m_events'];
}
}
return $nbClicks;
}
/**
* @throws TransportExceptionInterface
*/
private function getResponse($datas): ResponseInterface
{
return $this->httpClient->request('POST', $this->urlAt, [
'headers' => [
'Content-Type' => 'application/json',
'x-api-key' => $this->apiKey
],
'body' => json_encode($datas)
]);
}
}