From f3d040adbd7decdd2cdd93d83f0dbf1833b1429f Mon Sep 17 00:00:00 2001
From: sgiehl
Date: Mon, 3 Jul 2023 11:29:46 +0200
Subject: [PATCH 01/35] refactor site content detection and no data page
---
core/SiteContentDetector.php | 137 +++++------
plugins/Installation/Controller.php | 2 -
plugins/SitesManager/Controller.php | 223 +++++++++---------
plugins/SitesManager/GtmSiteTypeGuesser.php | 186 ---------------
.../SiteContentDetection/Cloudflare.php | 77 ++++++
.../SiteContentDetection/Drupal.php | 45 ++++
.../SiteContentDetection/GoogleAnalytics3.php | 48 ++++
.../SiteContentDetection/GoogleAnalytics4.php | 45 ++++
.../SiteContentDetection/GoogleTagManager.php | 96 ++++++++
.../SiteContentDetection/Joomla.php | 40 ++++
.../SiteContentDetection/MatomoTagManager.php | 68 ++++++
.../SiteContentDetection/ReactJs.php | 99 ++++++++
.../SiteContentDetection/Sharepoint.php | 35 +++
.../SiteContentDetection/Shopify.php | 35 +++
.../SiteContentDetectionAbstract.php | 102 ++++++++
.../SiteContentDetection/SpaPwa.php | 60 +++++
.../SiteContentDetection/Squarespace.php | 35 +++
.../SiteContentDetection/VueJs.php | 121 ++++++++++
.../SiteContentDetection/Webflow.php | 35 +++
.../SitesManager/SiteContentDetection/Wix.php | 35 +++
.../SiteContentDetection/Wordpress.php | 92 ++++++++
plugins/SitesManager/SitesManager.php | 73 +-----
.../templates/_cloudflareTabInstructions.twig | 25 ++
.../templates/_gtmTabInstructions.twig | 9 +
.../templates/_siteWithoutDataTabs.twig | 191 ++-------------
plugins/SitesManager/templates/_spa.twig | 6 -
.../templates/_trackingCodeEmail.twig | 14 +-
.../templates/_vueTabInstructions.twig | 9 +
.../templates/_wordpressTabInstructions.twig | 4 +
.../PHPUnit/Unit/SiteContentDetectorTest.php | 52 +---
30 files changed, 1334 insertions(+), 665 deletions(-)
delete mode 100644 plugins/SitesManager/GtmSiteTypeGuesser.php
create mode 100644 plugins/SitesManager/SiteContentDetection/Cloudflare.php
create mode 100644 plugins/SitesManager/SiteContentDetection/Drupal.php
create mode 100644 plugins/SitesManager/SiteContentDetection/GoogleAnalytics3.php
create mode 100644 plugins/SitesManager/SiteContentDetection/GoogleAnalytics4.php
create mode 100644 plugins/SitesManager/SiteContentDetection/GoogleTagManager.php
create mode 100644 plugins/SitesManager/SiteContentDetection/Joomla.php
create mode 100644 plugins/SitesManager/SiteContentDetection/MatomoTagManager.php
create mode 100644 plugins/SitesManager/SiteContentDetection/ReactJs.php
create mode 100644 plugins/SitesManager/SiteContentDetection/Sharepoint.php
create mode 100644 plugins/SitesManager/SiteContentDetection/Shopify.php
create mode 100644 plugins/SitesManager/SiteContentDetection/SiteContentDetectionAbstract.php
create mode 100644 plugins/SitesManager/SiteContentDetection/SpaPwa.php
create mode 100644 plugins/SitesManager/SiteContentDetection/Squarespace.php
create mode 100644 plugins/SitesManager/SiteContentDetection/VueJs.php
create mode 100644 plugins/SitesManager/SiteContentDetection/Webflow.php
create mode 100644 plugins/SitesManager/SiteContentDetection/Wix.php
create mode 100644 plugins/SitesManager/SiteContentDetection/Wordpress.php
create mode 100644 plugins/SitesManager/templates/_cloudflareTabInstructions.twig
delete mode 100644 plugins/SitesManager/templates/_spa.twig
diff --git a/core/SiteContentDetector.php b/core/SiteContentDetector.php
index d551164c2f5..14a7f82932a 100644
--- a/core/SiteContentDetector.php
+++ b/core/SiteContentDetector.php
@@ -12,7 +12,11 @@
use Matomo\Cache\Lazy;
use Piwik\Config\GeneralConfig;
-use Piwik\Plugins\SitesManager\GtmSiteTypeGuesser;
+use Piwik\Container\StaticContainer;
+use Piwik\Plugins\SitesManager\SiteContentDetection\GoogleAnalytics3;
+use Piwik\Plugins\SitesManager\SiteContentDetection\GoogleAnalytics4;
+use Piwik\Plugins\SitesManager\SiteContentDetection\GoogleTagManager;
+use Piwik\Plugins\SitesManager\SiteContentDetection\SiteContentDetectionAbstract;
use Piwik\Plugins\SitesManager\SitesManager;
/**
@@ -48,13 +52,16 @@ class SiteContentDetector
public $consentManagerName; // Display name of the detected consent manager, eg. 'Osano'
public $consentManagerUrl; // Url for the configuration guide for the detected consent manager
public $isConnected = false; // True if the detected consent manager is already connected with Matomo
- public $ga3; // True if GA3 was detected on the site
- public $ga4; // True if GA4 was detected on the site
- public $gtm; // True if GTM was detected on the site
- public $cms; // The CMS that was detected on the site
- public $cloudflare; // true if website is hosted on cloudflare
- public $jsFramework; // The JS framework that was detected on the site
+ /**
+ * @var array>
+ */
+ public $detectedContent = [
+ SiteContentDetectionAbstract::TYPE_TRACKER => [],
+ SiteContentDetectionAbstract::TYPE_CMS => [],
+ SiteContentDetectionAbstract::TYPE_JS_FRAMEWORK => [],
+ SiteContentDetectionAbstract::TYPE_CONSENT_MANAGER => [],
+ ];
private $siteResponse = [
'data' => '',
'headers' => []
@@ -63,11 +70,6 @@ class SiteContentDetector
/** @var Lazy */
private $cache;
- /**
- * @var GtmSiteTypeGuesser
- */
- private $siteGuesser;
-
public function __construct(?Lazy $cache = null)
{
if ($cache === null) {
@@ -75,7 +77,47 @@ public function __construct(?Lazy $cache = null)
} else {
$this->cache = $cache;
}
- $this->siteGuesser = new GtmSiteTypeGuesser();
+ }
+
+
+ /**
+ * @return array
+ */
+ public function getSiteContentDetectionsByType()
+ {
+ $instancesByType = [];
+ $classes = $this->getAllSiteContentDetectionClasses();
+
+ foreach ($classes as $className) {
+ $instancesByType[$className::getContentType()][] = StaticContainer::get($className);
+ }
+
+ return $instancesByType;
+ }
+
+ /**
+ * @param string $id
+ * @return SiteContentDetectionAbstract|null
+ */
+ public function getSiteContentDetectionById(string $id): ?SiteContentDetectionAbstract
+ {
+ $classes = $this->getAllSiteContentDetectionClasses();
+
+ foreach ($classes as $className) {
+ if ($className::getId() === $id) {
+ return StaticContainer::get($className);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @return string[]
+ */
+ protected function getAllSiteContentDetectionClasses(): array
+ {
+ return Plugin\Manager::getInstance()->findMultipleComponents('SiteContentDetection', SiteContentDetectionAbstract::class);
}
/**
@@ -89,12 +131,6 @@ private function resetDetectionProperties(): void
$this->consentManagerUrl = null;
$this->consentManagerName = null;
$this->isConnected = false;
- $this->ga3 = false;
- $this->ga4 = false;
- $this->gtm = false;
- $this->cms = SitesManager::SITE_TYPE_UNKNOWN;
- $this->cloudflare = false;
- $this->jsFramework = SitesManager::JS_FRAMEWORK_UNKNOWN;
}
/**
@@ -181,26 +217,6 @@ private function getRequiredProperties(array $detectContent): array
$requiredProperties = array_merge($requiredProperties, ['consentManagerId', 'consentManagerName', 'consentManagerUrl', 'isConnected']);
}
- if (in_array(SiteContentDetector::GA3, $detectContent) || in_array(SiteContentDetector::ALL_CONTENT, $detectContent)) {
- $requiredProperties[] = 'ga3';
- }
-
- if (in_array(SiteContentDetector::GA4, $detectContent) || in_array(SiteContentDetector::ALL_CONTENT, $detectContent)) {
- $requiredProperties[] = 'ga4';
- }
-
- if (in_array(SiteContentDetector::GTM, $detectContent) || in_array(SiteContentDetector::ALL_CONTENT, $detectContent)) {
- $requiredProperties[] = 'gtm';
- }
-
- if (in_array(SiteContentDetector::CMS, $detectContent) || in_array(SiteContentDetector::ALL_CONTENT, $detectContent)) {
- $requiredProperties[] = 'cms';
- }
-
- if (in_array(SiteContentDetector::JS_FRAMEWORK, $detectContent) || in_array(SiteContentDetector::ALL_CONTENT, $detectContent)) {
- $requiredProperties[] = 'jsFramework';
- }
-
return $requiredProperties;
}
@@ -282,35 +298,20 @@ private function detectionChecks($detectContent): void
$this->detectConsentManager();
}
- if (in_array(SiteContentDetector::GA3, $detectContent) || in_array(SiteContentDetector::ALL_CONTENT, $detectContent)) {
- $this->ga3 = $this->siteGuesser->detectGA3FromResponse($this->siteResponse);
- }
-
- if (in_array(SiteContentDetector::GA4, $detectContent) || in_array(SiteContentDetector::ALL_CONTENT, $detectContent)) {
- $this->ga4 = $this->siteGuesser->detectGA4FromResponse($this->siteResponse);
- }
-
- if (in_array(SiteContentDetector::GTM, $detectContent) || in_array(SiteContentDetector::ALL_CONTENT, $detectContent)) {
- $this->gtm = $this->siteGuesser->guessGtmFromResponse($this->siteResponse);
- }
-
- if (in_array(SiteContentDetector::CMS, $detectContent) || in_array(SiteContentDetector::ALL_CONTENT, $detectContent)) {
- $this->cms = $this->siteGuesser->guessSiteTypeFromResponse($this->siteResponse);
- }
-
- if (in_array(SiteContentDetector::JS_FRAMEWORK, $detectContent) || in_array(SiteContentDetector::ALL_CONTENT, $detectContent)) {
- $this->jsFramework = $this->siteGuesser->guessJsFrameworkFromResponse($this->siteResponse);
- }
-
- if (
- (!empty($this->siteResponse['headers']['server']) && stripos($this->siteResponse['headers']['server'], 'cloudflare') !== false) ||
- (!empty($this->siteResponse['headers']['Server']) && stripos($this->siteResponse['headers']['Server'], 'cloudflare') !== false) ||
- (!empty($this->siteResponse['headers']['SERVER']) && stripos($this->siteResponse['headers']['SERVER'], 'cloudflare') !== false) ||
- !empty($this->siteResponse['headers']['cf-ray']) ||
- !empty($this->siteResponse['headers']['Cf-Ray']) ||
- !empty($this->siteResponse['headers']['CF-RAY'])
- ) {
- $this->cloudflare = true;
+ $detections = $this->getSiteContentDetectionsByType();
+
+ foreach ($detections as $type => $typeDetections) {
+ foreach ($typeDetections as $typeDetection) {
+ if (in_array($type, $detectContent) ||
+ in_array($typeDetection::getId(), $detectContent) ||
+ in_array(SiteContentDetector::ALL_CONTENT, $detectContent))
+ {
+ if (!$typeDetection->showInstructionTabOnlyOnDetection() ||
+ $typeDetection->detectSiteByContent($this->siteResponse['data'], $this->siteResponse['headers'])) {
+ $this->detectedContent[$type][] = $typeDetection::getId();
+ }
+ }
+ }
}
}
diff --git a/plugins/Installation/Controller.php b/plugins/Installation/Controller.php
index 04ab0a06096..cb84af57137 100644
--- a/plugins/Installation/Controller.php
+++ b/plugins/Installation/Controller.php
@@ -411,7 +411,6 @@ public function trackingCode()
'ga3Used' => $this->siteContentDetector->ga3,
'ga4Used' => $this->siteContentDetector->ga4,
'cloudflare' => $this->siteContentDetector->cloudflare,
- 'jsFramework' => $this->siteContentDetector->jsFramework,
'consentManagerName' => $this->siteContentDetector->consentManagerName,
'consentManagerUrl' => $this->siteContentDetector->consentManagerUrl,
'consentManagerIsConnected' => $this->siteContentDetector->isConnected
@@ -430,7 +429,6 @@ public function trackingCode()
$viewTrackingHelp->ga3Used = $this->siteContentDetector->ga3;
$viewTrackingHelp->ga4Used = $this->siteContentDetector->ga4;
$viewTrackingHelp->cloudflare = $this->siteContentDetector->cloudflare;
- $viewTrackingHelp->jsFramework = $this->siteContentDetector->jsFramework;
$viewTrackingHelp->consentManagerName = $this->siteContentDetector->consentManagerName;
$viewTrackingHelp->consentManagerUrl = $this->siteContentDetector->consentManagerUrl;
$viewTrackingHelp->consentManagerIsConnected = $this->siteContentDetector->isConnected;
diff --git a/plugins/SitesManager/Controller.php b/plugins/SitesManager/Controller.php
index 3921a25a44c..4b2a98d62ca 100644
--- a/plugins/SitesManager/Controller.php
+++ b/plugins/SitesManager/Controller.php
@@ -20,6 +20,14 @@
use Piwik\Plugin;
use Piwik\Plugins\CustomVariables\CustomVariables;
use Piwik\Plugins\PrivacyManager\DoNotTrackHeaderChecker;
+use Piwik\Plugins\SitesManager\SiteContentDetection\Cloudflare;
+use Piwik\Plugins\SitesManager\SiteContentDetection\GoogleAnalytics3;
+use Piwik\Plugins\SitesManager\SiteContentDetection\GoogleAnalytics4;
+use Piwik\Plugins\SitesManager\SiteContentDetection\GoogleTagManager;
+use Piwik\Plugins\SitesManager\SiteContentDetection\ReactJs;
+use Piwik\Plugins\SitesManager\SiteContentDetection\SiteContentDetectionAbstract;
+use Piwik\Plugins\SitesManager\SiteContentDetection\VueJs;
+use Piwik\Plugins\SitesManager\SiteContentDetection\Wordpress;
use Piwik\Site;
use Piwik\SiteContentDetector;
use Piwik\Session;
@@ -27,22 +35,17 @@
use Piwik\Tracker\TrackerCodeGenerator;
use Piwik\Translation\Translator;
use Piwik\Url;
-use Matomo\Cache\Lazy;
/**
*
*/
class Controller extends \Piwik\Plugin\ControllerAdmin
{
- /** @var Lazy */
- private $cache;
-
/** @var SiteContentDetector */
private $siteContentDetector;
- public function __construct(Lazy $cache, SiteContentDetector $siteContentDetector)
+ public function __construct(SiteContentDetector $siteContentDetector)
{
- $this->cache = $cache;
$this->siteContentDetector = $siteContentDetector;
parent::__construct();
@@ -163,25 +166,16 @@ public function siteWithoutData()
'trackingUrl' => $trackingUrl,
'idSite' => $this->idSite,
'consentManagerName' => false,
- 'cloudflare' => false,
- 'ga3Used' => false,
- 'ga4Used' => false,
- 'gtmUsed' => false,
- 'cms' => false,
- 'jsFramework' => false,
];
- $this->siteContentDetector->detectContent([SiteContentDetector::ALL_CONTENT]);
+ $this->siteContentDetector->detectContent();
if ($this->siteContentDetector->consentManagerId) {
$emailTemplateData['consentManagerName'] = $this->siteContentDetector->consentManagerName;
$emailTemplateData['consentManagerUrl'] = $this->siteContentDetector->consentManagerUrl;
}
- $emailTemplateData['ga3Used'] = $this->siteContentDetector->ga3;
- $emailTemplateData['ga4Used'] = $this->siteContentDetector->ga4;
- $emailTemplateData['gtmUsed'] = $this->siteContentDetector->gtm;
- $emailTemplateData['cloudflare'] = $this->siteContentDetector->cloudflare;
- $emailTemplateData['cms'] = $this->siteContentDetector->cms;
- $emailTemplateData['jsFramework'] = $this->siteContentDetector->jsFramework;
+ $emailTemplateData['cms'] = $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_CMS];
+ $emailTemplateData['jsFrameworks'] = $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_JS_FRAMEWORK];
+ $emailTemplateData['trackers'] = $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_TRACKER];
$emailContent = $this->renderTemplateAs('@SitesManager/_trackingCodeEmail', $emailTemplateData, $viewType = 'basic');
$inviteUserLink = $this->getInviteUserLink();
@@ -192,7 +186,6 @@ public function siteWithoutData()
'piwikUrl' => $piwikUrl,
'emailBody' => $emailContent,
'siteWithoutDataStartTrackingTranslationKey' => StaticContainer::get('SitesManager.SiteWithoutDataStartTrackingTranslation'),
- 'SiteWithoutDataVueFollowStepNote2Key' => StaticContainer::get('SitesManager.SiteWithoutDataVueFollowStepNote2'),
'inviteUserLink' => $inviteUserLink
], $viewType = 'basic');
}
@@ -227,10 +220,6 @@ public function siteWithoutDataTabs()
Piwik::postEvent('SitesManager.siteWithoutData.customizeImporterMessage', [&$googleAnalyticsImporterMessage]);
}
- $tagManagerActive = false;
- if (Manager::getInstance()->isPluginActivated('TagManager')) {
- $tagManagerActive = true;
- }
$this->siteContentDetector->detectContent([SiteContentDetector::ALL_CONTENT], $this->idSite);
$dntChecker = new DoNotTrackHeaderChecker();
@@ -240,18 +229,12 @@ public function siteWithoutDataTabs()
'jsTag' => $jsTag,
'piwikUrl' => $piwikUrl,
'showMatomoLinks' => $showMatomoLinks,
- 'siteType' => $this->siteContentDetector->cms,
- 'instruction' => SitesManager::getInstructionByCms($this->siteContentDetector->cms),
- 'gtmUsed' => $this->siteContentDetector->gtm,
- 'ga3Used' => $this->siteContentDetector->ga3,
- 'ga4Used' => $this->siteContentDetector->ga4,
+ 'cms' => $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_CMS],
+ 'trackers' => $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_TRACKER],
+ 'jsFrameworks' => $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_JS_FRAMEWORK],
+ 'instruction' => $this->getCmsInstruction(),
'googleAnalyticsImporterMessage' => $googleAnalyticsImporterMessage,
- 'tagManagerActive' => $tagManagerActive,
'consentManagerName' => false,
- 'cloudflare' => $this->siteContentDetector->cloudflare,
- 'jsFramework' => $this->siteContentDetector->jsFramework,
- 'cms' => $this->siteContentDetector->cms,
- 'SiteWithoutDataVueFollowStepNote2Key' => StaticContainer::get('SitesManager.SiteWithoutDataVueFollowStepNote2'),
'defaultSiteDecoded' => [
'id' => $this->idSite,
'name' => Common::unsanitizeInputValue(Site::getNameFor($this->idSite)),
@@ -261,42 +244,109 @@ public function siteWithoutDataTabs()
'isJsTrackerInstallCheckAvailable' => Manager::getInstance()->isPluginActivated('JsTrackerInstallCheck'),
];
- $templateData['showGAImportTab'] = $this->shouldShowGAImportTab($templateData);
-
if ($this->siteContentDetector->consentManagerId) {
$templateData['consentManagerName'] = $this->siteContentDetector->consentManagerName;
$templateData['consentManagerUrl'] = $this->siteContentDetector->consentManagerUrl;
$templateData['consentManagerIsConnected'] = $this->siteContentDetector->isConnected;
}
- $templateData['activeTab'] = $this->getActiveTabOnLoad($templateData);
-
- if ($this->siteContentDetector->jsFramework === SitesManager::JS_FRAMEWORK_VUE) {
- $templateData['vue3Code'] = $this->getVueInitializeCode(3);
- $templateData['vue2Code'] = $this->getVueInitializeCode(2);
+ $templateData['tabs'] = [];
+ $templateData['instructionUrls'] = [];
+ $templateData['othersInstructions'] = [];
+
+ foreach ($this->siteContentDetector->getSiteContentDetectionsByType() as $detections) {
+ foreach ($detections as $obj) {
+ $tabContent = $obj->renderInstructionsTab();
+ $othersInstruction = $obj->renderOthersInstruction();
+ $instructionUrl = $obj->getInstructionUrl();
+
+ Piwik::postEvent('Template.siteWithoutDataTab.' . $obj::getId() . '.content', [&$tabContent]);
+
+ if (!empty($tabContent) && in_array($obj::getId(), $this->siteContentDetector->detectedContent[$obj::getContentType()])) {
+ $templateData['tabs'][] = [
+ 'id' => $obj::getId(),
+ 'name' => $obj::getName(),
+ 'type' => $obj::getContentType(),
+ 'content' => $tabContent,
+ 'priority' => $obj::getPriority(),
+ ];
+ }
+
+ if (!empty($othersInstruction)) {
+ $templateData['othersInstructions'][] = [
+ 'id' => $obj::getId(),
+ 'name' => $obj::getName(),
+ 'type' => $obj::getContentType(),
+ 'othersInstruction' => $obj->renderOthersInstruction(),
+ ];
+ }
+
+ if (!empty($instructionUrl)) {
+ $templateData['instructionUrls'][] = [
+ 'id' => $obj::getId(),
+ 'name' => $obj::getName(),
+ 'type' => $obj::getContentType(),
+ 'instructionUrl' => $obj::getInstructionUrl(),
+ ];
+ }
+ }
}
+ usort($templateData['tabs'], function($a, $b) {
+ return strcmp($a['priority'], $b['priority']);
+ });
+
+ usort($templateData['othersInstructions'], function($a, $b) {
+ return strnatcmp($a['name'], $b['name']);
+ });
+
+ usort($templateData['instructionUrls'], function($a, $b) {
+ return strnatcmp($a['name'], $b['name']);
+ });
+
+ $templateData['activeTab'] = $this->getActiveTabOnLoad($templateData);
$this->mergeMultipleNotification($templateData);
return $this->renderTemplateAs('_siteWithoutDataTabs', $templateData, $viewType = 'basic');
}
+ private function getCmsInstruction()
+ {
+ if (empty($this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_CMS])
+ || in_array(Wordpress::getId(), $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_CMS])) {
+ return '';
+ }
+
+ $detectedCms = $this->siteContentDetector->getSiteContentDetectionById(reset($this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_CMS]));
+
+ if (null === $detectedCms) {
+ return '';
+ }
+
+ Piwik::translate(
+ 'SitesManager_SiteWithoutDataDetectedSite',
+ [
+ $detectedCms::getName(),
+ '',
+ ''
+ ]
+ );
+ }
+
private function getActiveTabOnLoad($templateData)
{
$tabToDisplay = '';
- if (!empty($templateData['gtmUsed'])) {
- $tabToDisplay = 'gtm';
- } else if (!empty($templateData['cms']) && $templateData['cms'] === SitesManager::SITE_TYPE_WORDPRESS) {
- $tabToDisplay = 'wordpress';
- } else if (!empty($templateData['showGAImportTab'])) {
- $tabToDisplay = 'ga-import';
- } else if (!empty($templateData['cloudflare'])) {
- $tabToDisplay = 'cloudflare';
- } else if (!empty($templateData['jsFramework']) && $templateData['jsFramework'] === SitesManager::JS_FRAMEWORK_VUE) {
- $tabToDisplay = 'vue';
- } else if (!empty($templateData['jsFramework']) && $templateData['jsFramework'] === SitesManager::JS_FRAMEWORK_REACT && Manager::getInstance()->isPluginActivated('TagManager')) {
- $tabToDisplay = 'react';
+ if (!empty(in_array(GoogleTagManager::getId(), $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_TRACKER]))) {
+ $tabToDisplay = GoogleTagManager::getId();
+ } else if (in_array(Wordpress::getId(), $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_CMS])) {
+ $tabToDisplay = Wordpress::getId();
+ } else if (in_array(Cloudflare::getId(), $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_CMS])) {
+ $tabToDisplay = Cloudflare::getId();
+ } else if (in_array(VueJs::getId(), $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_JS_FRAMEWORK])) {
+ $tabToDisplay = VueJs::getId();
+ } else if (in_array(ReactJs::getId(), $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_TRACKER]) && Manager::getInstance()->isPluginActivated('TagManager')) {
+ $tabToDisplay = ReactJs::getId();
} else if (!empty($templateData['consentManagerName'])) {
$tabToDisplay = 'consentManager';
}
@@ -319,60 +369,16 @@ private function getInviteUserLink()
]);
}
- private function getVueInitializeCode($vueVersion = '3')
- {
- $request = \Piwik\Request::fromRequest();
- $piwikUrl = Url::getCurrentUrlWithoutFileName();
- $siteId = $request->getIntegerParameter('idSite', 1);
- $configureComment = Piwik::translate('SitesManager_SiteWithoutDataVueFollowStep2ExampleCodeCommentConfigureMatomo');
- $trackViewComment = Piwik::translate('SitesManager_SiteWithoutDataVueFollowStep2ExampleCodeCommentTrackPageView');
- if ($vueVersion == 2) {
- return <<siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_TRACKER]);
+ $ga4Used = in_array(GoogleAnalytics4::getId(), $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_TRACKER]);
- if ($templateData['ga3Used'] || $templateData['ga4Used']) {
+ if ($ga3Used || $ga4Used) {
$message[0] = 'Google Analytics ';
$ga3GuideUrl = 'Google Analytics 3';
$ga4GuideUrl = 'Google Analytics 4';
@@ -382,8 +388,8 @@ private function mergeMultipleNotification(&$templateData)
$guides[] = $ga4GuideUrl;
$message[0] .= '3 & 4';
} else {
- $message[0] .= ($templateData['ga3Used'] ? 3 : 4);
- $guides[] = ($templateData['ga3Used'] ? $ga3GuideUrl : $ga4GuideUrl);
+ $message[0] .= ($ga3Used ? 3 : 4);
+ $guides[] = ($ga3Used ? $ga3GuideUrl : $ga4GuideUrl);
}
}
@@ -421,21 +427,12 @@ private function getSingleNotifications(&$templateData)
if (!empty($templateData['consentManagerIsConnected'])) {
$info['notificationMessage'] .= '' . Piwik::translate('SitesManager_ConsentManagerConnected', [$templateData['consentManagerName']]) . '
';
}
- } else if (!empty($templateData['ga3Used'])) {
+ } else if (in_array(GoogleAnalytics3::getId(), $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_TRACKER])) {
$info['notificationMessage'] = '' . Piwik::translate('SitesManager_GADetected', ['Google Analytics 3', 'GA', '', '', '', '']) . '
';
- } else if (!empty($templateData['ga4Used'])) {
+ } else if (in_array(GoogleAnalytics4::getId(), $this->siteContentDetector->detectedContent[SiteContentDetectionAbstract::TYPE_TRACKER])) {
$info['notificationMessage'] = '' . Piwik::translate('SitesManager_GADetected', ['Google Analytics 4', 'GA', '', '', '', '']) . '
';
}
return $info;
}
-
- private function shouldShowGAImportTab($templateData)
- {
- if (Piwik::hasUserSuperUserAccess() && Manager::getInstance()->isPluginActivated('GoogleAnalyticsImporter') && (!empty($templateData['ga3Used']) || !empty($templateData['ga4Used']))) {
- return true;
- }
-
- return false;
- }
}
diff --git a/plugins/SitesManager/GtmSiteTypeGuesser.php b/plugins/SitesManager/GtmSiteTypeGuesser.php
deleted file mode 100644
index 6cb02c67f85..00000000000
--- a/plugins/SitesManager/GtmSiteTypeGuesser.php
+++ /dev/null
@@ -1,186 +0,0 @@
-';
- if (strpos($response['data'], $needle) !== false) {
- return SitesManager::SITE_TYPE_SQUARESPACE;
- }
-
- $needle = 'X-Wix-Published-Version';
- if (strpos($response['data'], $needle) !== false) {
- return SitesManager::SITE_TYPE_WIX;
- }
-
- // https://github.com/joomla/joomla-cms/blob/staging/libraries/src/Application/WebApplication.php#L516
- // Joomla was the outcome of a fork of Mambo on 17 August 2005 - https://en.wikipedia.org/wiki/Joomla
- if (isset($response['headers']['expires']) && $response['headers']['expires'] === 'Wed, 17 Aug 2005 00:00:00 GMT') {
- return SitesManager::SITE_TYPE_JOOMLA;
- }
-
- $needle = 'Shopify.theme';
- if (strpos($response['data'], $needle) !== false) {
- return SitesManager::SITE_TYPE_SHOPIFY;
- }
-
- $needle = 'content="Microsoft SharePoint';
- if (strpos($response['data'], $needle) !== false) {
- return SitesManager::SITE_TYPE_SHAREPOINT;
- }
-
- $needle = 'idSite = Request::fromRequest()->getIntegerParameter('idSite');
+ $view->sendHeadersWhenRendering = false;
+ return $view->render();
+ }
+
+ public function renderOthersInstruction(): string
+ {
+ return sprintf(
+ '%s
',
+ Piwik::translate(
+ 'SitesManager_SiteWithoutDataCloudflareDescription',
+ [
+ '',
+ ''
+ ]
+ )
+ );
+ }
+}
diff --git a/plugins/SitesManager/SiteContentDetection/Drupal.php b/plugins/SitesManager/SiteContentDetection/Drupal.php
new file mode 100644
index 00000000000..64c1d82ff98
--- /dev/null
+++ b/plugins/SitesManager/SiteContentDetection/Drupal.php
@@ -0,0 +1,45 @@
+ \Piwik\Request::fromRequest()->getIntegerParameter('idSite'),
+ 'piwikUrl' => $piwikUrl
+ ]
+ );
+ $view = new View('@SitesManager/_gtmTabInstructions');
+ $view->jsTag = $jsTag;
+ $view->sendHeadersWhenRendering = false;
+ return $view->render();
+ }
+
+ public function renderOthersInstruction(): string
+ {
+ return sprintf(
+ '%s
',
+ Piwik::translate(
+ 'SitesManager_SiteWithoutDataGoogleTagManagerDescription',
+ [
+ '',
+ ''
+ ]
+ )
+ );
+ }
+}
diff --git a/plugins/SitesManager/SiteContentDetection/Joomla.php b/plugins/SitesManager/SiteContentDetection/Joomla.php
new file mode 100644
index 00000000000..23eb9e45552
--- /dev/null
+++ b/plugins/SitesManager/SiteContentDetection/Joomla.php
@@ -0,0 +1,40 @@
+' . Piwik::translate('SitesManager_SiteWithoutDataMatomoTagManager') . '
+ ' . Piwik::translate( 'SitesManager_SiteWithoutDataMatomoTagManagerNotActive', ['', '']) . '
';
+ }
+
+ public function renderOthersInstruction(): string
+ {
+ return sprintf(
+ '%s
',
+ Piwik::translate(
+ 'SitesManager_SiteWithoutDataGoogleTagManagerDescription',
+ [
+ '',
+ ''
+ ]
+ )
+ );
+ }
+}
diff --git a/plugins/SitesManager/SiteContentDetection/ReactJs.php b/plugins/SitesManager/SiteContentDetection/ReactJs.php
new file mode 100644
index 00000000000..a916d7b0eba
--- /dev/null
+++ b/plugins/SitesManager/SiteContentDetection/ReactJs.php
@@ -0,0 +1,99 @@
+
+
+ ' . Piwik::translate(
+ 'SitesManager_ReactDetected',
+ [
+ '
',
+ '',
+ '
',
+ ''
+ ]
+ ) . '
+
+
+
+
+
+';
+ }
+
+ public function renderOthersInstruction(): string
+ {
+ return sprintf(
+ '%s
',
+ Piwik::translate(
+ 'SitesManager_SiteWithoutDataReactDescription',
+ [
+ '',
+ '',
+ '',
+ '',
+ ]
+ )
+ );
+ }
+}
diff --git a/plugins/SitesManager/SiteContentDetection/Sharepoint.php b/plugins/SitesManager/SiteContentDetection/Sharepoint.php
new file mode 100644
index 00000000000..f7732afd566
--- /dev/null
+++ b/plugins/SitesManager/SiteContentDetection/Sharepoint.php
@@ -0,0 +1,35 @@
+%s',
+ Piwik::translate(
+ 'SitesManager_SiteWithoutDataSinglePageApplicationDescription',
+ [
+ '',
+ '',
+ ]
+ )
+ );
+ }
+}
diff --git a/plugins/SitesManager/SiteContentDetection/Squarespace.php b/plugins/SitesManager/SiteContentDetection/Squarespace.php
new file mode 100644
index 00000000000..10ef92468f0
--- /dev/null
+++ b/plugins/SitesManager/SiteContentDetection/Squarespace.php
@@ -0,0 +1,35 @@
+';
+ return (strpos($data, $needle) !== false);
+ }
+}
diff --git a/plugins/SitesManager/SiteContentDetection/VueJs.php b/plugins/SitesManager/SiteContentDetection/VueJs.php
new file mode 100644
index 00000000000..f44d30b9a0f
--- /dev/null
+++ b/plugins/SitesManager/SiteContentDetection/VueJs.php
@@ -0,0 +1,121 @@
+sendHeadersWhenRendering = false;
+ $view->SiteWithoutDataVueFollowStepNote2Key = StaticContainer::get('SitesManager.SiteWithoutDataVueFollowStepNote2');
+ $view->vue3Code = $this->getVueInitializeCode(3);
+ $view->vue2Code = $this->getVueInitializeCode(2);
+ return $view->render();
+ }
+
+ public function renderOthersInstruction(): string
+ {
+ return sprintf(
+ '%s
',
+ Piwik::translate(
+ 'SitesManager_SiteWithoutDataVueDescription',
+ [
+ 'vue-matomo',
+ '',
+ ''
+ ]
+ )
+ );
+ }
+
+ private function getVueInitializeCode($vueVersion = '3')
+ {
+ $request = \Piwik\Request::fromRequest();
+ $piwikUrl = Url::getCurrentUrlWithoutFileName();
+ $siteId = $request->getIntegerParameter('idSite', 1);
+ $configureComment = Piwik::translate('SitesManager_SiteWithoutDataVueFollowStep2ExampleCodeCommentConfigureMatomo');
+ $trackViewComment = Piwik::translate('SitesManager_SiteWithoutDataVueFollowStep2ExampleCodeCommentTrackPageView');
+ if ($vueVersion == 2) {
+ return <<getIntegerParameter('idSite', 0);
+ $period = $request->getStringParameter('period', 'day');
+ $date = $request->getStringParameter('date', 'yesterday');
+ $authLink = SettingsPiwik::getPiwikUrl() . 'index.php?' .
+ Url::getQueryStringFromParameters([
+ 'idSite' => $idSite,
+ 'date' => $date,
+ 'period' => $period,
+ 'module' => 'UsersManager',
+ 'action' => 'addNewToken',
+ ]);
+ }
+ $view->authLink = $authLink;
+ $view->faqLink = $faqLink;
+ $view->sendHeadersWhenRendering = false;
+ $view->site = ['id' => $idSite, 'name' => ''];
+ $view->isJsTrackerInstallCheckAvailable = Manager::getInstance()->isPluginActivated('JsTrackerInstallCheck');
+ return $view->render();
+ }
+
+ public function renderOthersInstruction(): string
+ {
+ return sprintf(
+ '%s
',
+ Piwik::translate(
+ 'SitesManager_SiteWithoutDataWordpressDescription',
+ [
+ '',
+ '',
+ ]
+ )
+ );
+ }
+}
diff --git a/plugins/SitesManager/SitesManager.php b/plugins/SitesManager/SitesManager.php
index aff32dc11c6..b4e22df8110 100644
--- a/plugins/SitesManager/SitesManager.php
+++ b/plugins/SitesManager/SitesManager.php
@@ -20,6 +20,8 @@
use Piwik\Piwik;
use Piwik\Plugin\Manager;
use Piwik\Plugins\CoreHome\SystemSummary;
+use Piwik\Plugins\SitesManager\SiteContentDetection\SiteContentDetectionAbstract;
+use Piwik\Plugins\SitesManager\SiteContentDetection\Wordpress;
use Piwik\Settings\Storage\Backend\MeasurableSettingsTable;
use Piwik\SettingsPiwik;
use Piwik\Tracker\Cache;
@@ -46,7 +48,6 @@ class SitesManager extends \Piwik\Plugin
const SITE_TYPE_SHOPIFY = 'shopify';
const SITE_TYPE_WEBFLOW = 'webflow';
const SITE_TYPE_DRUPAL = 'drupal';
- const JS_FRAMEWORK_UNKNOWN = 'unknown';
const JS_FRAMEWORK_VUE = 'vue';
const JS_FRAMEWORK_REACT = 'react';
@@ -63,8 +64,6 @@ public function registerEvents()
'SitesManager.deleteSite.end' => 'onSiteDeleted',
'System.addSystemSummaryItems' => 'addSystemSummaryItems',
'Request.dispatch' => 'redirectDashboardToWelcomePage',
- 'Template.noDataPageGTMTabInstructions' => 'noDataPageGTMTabInstructions',
- 'Template.noDataPageWordpressTabInstructions' => 'noDataPageWordpressTabInstructions',
];
}
@@ -376,38 +375,6 @@ private function getTrackerHosts($urls)
return $hosts;
}
- public static function getInstructionUrlBySiteType($siteType)
- {
- $map = [
- self::SITE_TYPE_JOOMLA => 'https://matomo.org/faq/new-to-piwik/how-do-i-install-the-matomo-analytics-tracking-code-on-joomla',
- self::SITE_TYPE_SHAREPOINT => 'https://matomo.org/faq/how-to-install/faq_19424',
- self::SITE_TYPE_SHOPIFY => 'https://matomo.org/faq/new-to-piwik/how-do-i-install-the-matomo-tracking-code-on-my-shopify-store',
- self::SITE_TYPE_SQUARESPACE => 'https://matomo.org/faq/new-to-piwik/how-do-i-integrate-matomo-with-squarespace-website',
- self::SITE_TYPE_WIX => 'https://matomo.org/faq/new-to-piwik/how-do-i-install-the-matomo-analytics-tracking-code-on-wix',
- self::SITE_TYPE_WORDPRESS => 'https://matomo.org/faq/new-to-piwik/how-do-i-install-the-matomo-tracking-code-on-wordpress/',
- self::SITE_TYPE_DRUPAL => 'https://matomo.org/faq/new-to-piwik/how-to-integrate-with-drupal/',
- self::SITE_TYPE_WEBFLOW => 'https://matomo.org/faq/new-to-piwik/how-do-i-install-the-matomo-tracking-code-on-webflow',
- ];
-
- return $map[$siteType] ?? false;
- }
-
- public static function getInstructionByCms(?string $cms): string
- {
- if ($cms === self::SITE_TYPE_UNKNOWN || $cms === self::SITE_TYPE_WORDPRESS) {
- return '';
- }
-
- return Piwik::translate(
- 'SitesManager_SiteWithoutDataDetectedSite',
- [
- ucfirst($cms),
- '',
- ''
- ]
- );
- }
-
public function getClientSideTranslationKeys(&$translationKeys)
{
$translationKeys[] = "General_Save";
@@ -525,40 +492,4 @@ public function getClientSideTranslationKeys(&$translationKeys)
$translationKeys[] = "SitesManager_SiteWithoutDataVueDescription";
$translationKeys[] = "SitesManager_SiteWithoutDataReactDescription";
}
-
- public function noDataPageGTMTabInstructions(&$out)
- {
- Piwik::checkUserHasSomeViewAccess();
- $piwikUrl = Url::getCurrentUrlWithoutFileName();
- $jsTag = Request::processRequest('SitesManager.getJavascriptTag', ['idSite' => Common::getRequestVar('idSite'), 'piwikUrl' => $piwikUrl]);
- $view = new View("@SitesManager/_gtmTabInstructions");
- $view->jsTag = $jsTag;
- $out = $view->render();
- }
-
- public function noDataPageWordpressTabInstructions(&$out)
- {
- Piwik::checkUserHasSomeViewAccess();
- $view = new View("@SitesManager/_wordpressTabInstructions");
- $faqLink = 'https://matomo.org/faq/general/faq_114/';
- $authLink = '';
- if (Piwik::isUserHasSomeViewAccess()) {
- $request = \Piwik\Request::fromRequest();
- $idSite = $request->getIntegerParameter('idSite', 0);
- $period = $request->getStringParameter('period', 'day');
- $date = $request->getStringParameter('date', 'yesterday');
- $authLink = SettingsPiwik::getPiwikUrl() . 'index.php?' . Url::getQueryStringFromParameters([
- 'idSite' => $idSite,
- 'date' => $date,
- 'period' => $period,
- 'module' => 'UsersManager',
- 'action' => 'addNewToken',
- ]);
- }
- $view->authLink = $authLink;
- $view->faqLink = $faqLink;
- $view->site = ['id' => $idSite, 'name' => ''];
- $view->isJsTrackerInstallCheckAvailable = Manager::getInstance()->isPluginActivated('JsTrackerInstallCheck');
- $out = $view->render();
- }
}
diff --git a/plugins/SitesManager/templates/_cloudflareTabInstructions.twig b/plugins/SitesManager/templates/_cloudflareTabInstructions.twig
new file mode 100644
index 00000000000..ed722e5de28
--- /dev/null
+++ b/plugins/SitesManager/templates/_cloudflareTabInstructions.twig
@@ -0,0 +1,25 @@
+
+
+ {{ 'SitesManager_CloudflareDetected'|translate('
','')|raw }}
+
+
+
+
+
+{{ 'SitesManager_SiteWithoutDataCloudflareIntro'|translate }}
+
+{{ 'SitesManager_SiteWithoutDataCloudflareFollowStepsIntro'|translate }}
+
+ - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep01'|translate('','')|raw }}
+ - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep02'|translate }}
+ - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep03'|translate }}
+ - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep04'|translate }}
+ - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep05'|translate }}
+ - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep06'|translate }}
+ - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep07'|translate }}
Matomo URL: {{ piwikUrl }}
{{ 'SitesManager_EmailInstructionsYourSiteId'|translate('' ~ idSite ~ '
')|raw }}
+ - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep08'|translate }}
+ - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep09'|translate }}
+ - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep10'|translate }}
+
+
+{{ 'SitesManager_SiteWithoutDataCloudflareFollowStepCompleted'|translate('','')|raw }}
diff --git a/plugins/SitesManager/templates/_gtmTabInstructions.twig b/plugins/SitesManager/templates/_gtmTabInstructions.twig
index 3b8d225c6f7..173e7762435 100644
--- a/plugins/SitesManager/templates/_gtmTabInstructions.twig
+++ b/plugins/SitesManager/templates/_gtmTabInstructions.twig
@@ -1,3 +1,12 @@
+
+
+ {{ 'SitesManager_GTMDetected'|translate('
', '')|raw }}
+
+
+
+
+
+
{{ 'SitesManager_SiteWithoutDataGoogleTagManagerIntro'|translate('','')|raw }}
{{ 'SitesManager_SiteWithoutDataGoogleTagManagerFollowStepsIntro'|translate }}
diff --git a/plugins/SitesManager/templates/_siteWithoutDataTabs.twig b/plugins/SitesManager/templates/_siteWithoutDataTabs.twig
index 2a59c731363..53afaba0007 100644
--- a/plugins/SitesManager/templates/_siteWithoutDataTabs.twig
+++ b/plugins/SitesManager/templates/_siteWithoutDataTabs.twig
@@ -16,35 +16,18 @@
});
-{% set columnClass = activeTab ? 's2' : 's3' %}
+{% set columnClass = tabs|length ? 's2' : 's3' %}
@@ -53,8 +36,8 @@
{% if instruction %}
{{ instruction|raw }}
- {% if gtmUsed %}
-
{{ 'SitesManager_SiteWithoutDataDetectedGtm'|translate(siteType|capitalize, '','')|raw }}
+ {% if 'GoogleTagManager' in trackers %}
+
{{ 'SitesManager_SiteWithoutDataDetectedGtm'|translate('','')|raw }}
{% endif %}
{{ 'SitesManager_SiteWithoutDataOtherIntegrations'|translate }}: {{ 'CoreAdminHome_JSTrackingIntro3a'|translate('','')|raw }}
@@ -62,16 +45,9 @@
{{ 'SitesManager_InstallationGuidesIntro'|translate }}
- WordPress
- | Squarespace
- | Wix
- | SharePoint
- | Joomla
- | Shopify
- | Google Tag Manager
- | Cloudflare
- | Vue
- | React
+ {% for instructionUrl in instructionUrls %}
+ {% if not loop.first %} | {% endif %}{{ instructionUrl.name }}
+ {% endfor %}
{{ 'CoreAdminHome_JSTrackingIntro3a'|translate('','')|raw }}
@@ -101,116 +77,11 @@
>
-
- {% if tagManagerActive %}
- {{ postEvent('Template.endTrackingCodePage') }}
- {% else %}
-
{{ 'SitesManager_SiteWithoutDataMatomoTagManager'|translate }}
-
{{ 'SitesManager_SiteWithoutDataMatomoTagManagerNotActive'|translate('', '')|raw }}
- {% endif %}
-
-
- {% if gtmUsed %}
-
-
-
-
- {{ 'SitesManager_GTMDetected'|translate('
', '')|raw }}
-
-
-
-
-
- {{ postEvent('Template.noDataPageGTMTabInstructions') }}
-
-
- {% endif %}
-
- {% if cms == 'wordpress' %}
-
-
-
-
-
- {{ postEvent('Template.noDataPageWordpressTabInstructions') }}
-
-
- {% endif %}
-
- {% if cloudflare %}
-
-
-
-
- {{ 'SitesManager_CloudflareDetected'|translate('
','')|raw }}
-
-
-
-
-
-
{{ 'SitesManager_SiteWithoutDataCloudflareIntro'|translate }}
-
-
{{ 'SitesManager_SiteWithoutDataCloudflareFollowStepsIntro'|translate }}
-
- - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep01'|translate('','')|raw }}
- - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep02'|translate }}
- - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep03'|translate }}
- - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep04'|translate }}
- - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep05'|translate }}
- - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep06'|translate }}
- - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep07'|translate }}
Matomo URL: {{ piwikUrl }}
{{ 'SitesManager_EmailInstructionsYourSiteId'|translate('' ~ idSite ~ '
')|raw }}
- - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep08'|translate }}
- - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep09'|translate }}
- - {{ 'SitesManager_SiteWithoutDataCloudflareFollowStep10'|translate }}
-
-
-
{{ 'SitesManager_SiteWithoutDataCloudflareFollowStepCompleted'|translate('','')|raw }}
-
- {% endif %}
-
- {% if jsFramework == 'vue' %}
-
-
-
-
- {{ 'SitesManager_VueDetected'|translate('
vue-matomo','
','')|raw }}
-
-
-
-
-
- {% include '@SitesManager/_vueTabInstructions.twig' %}
-
+ {% for tab in tabs %}
+
+ {{ tab.content|raw }}
- {% endif %}
-
- {% if jsFramework == 'react' %}
-
-
-
-
- {{ 'SitesManager_ReactDetected'|translate('
','','
','')|raw }}
-
-
-
-
-
- {{ postEvent('Template.embedReactTagManagerTrackingCode') }}
-
-
- {% endif %}
-
- {% if tagManagerActive %}
-
- {% include '@SitesManager/_spa.twig' %}
-
- {% endif %}
-
- {% if showGAImportTab %}
-
- {{ postEvent('Template.embedGAImportNoData', ga3Used) }}
-
- {% endif %}
+ {% endfor %}
{{ 'SitesManager_OtherWaysTabDescription'|translate }}
@@ -229,30 +100,10 @@
{{ 'CoreAdminHome_HttpTrackingApi'|translate }}
{{ 'CoreAdminHome_HttpTrackingApiDescription'|translate('','')|raw }}
- {% if not gtmUsed %}
-
{{ 'SitesManager_SiteWithoutDataGoogleTagManager'|translate }}
-
{{ 'SitesManager_SiteWithoutDataGoogleTagManagerDescription'|translate('','')|raw }}
- {% endif %}
-
- {% if cms is not same as('wordpress') %}
-
WordPress
-
{{ 'SitesManager_SiteWithoutDataWordpressDescription'|translate('','')|raw }}
- {% endif %}
-
- {% if not cloudflare %}
-
Cloudflare
-
{{ 'SitesManager_SiteWithoutDataCloudflareDescription'|translate('','')|raw }}
- {% endif %}
-
- {% if jsFramework is not same as('vue') %}
-
Vue.js
-
{{ 'SitesManager_SiteWithoutDataVueDescription'|translate('vue-matomo', '','')|raw }}
- {% endif %}
-
- {% if jsFramework is not same as('react') %}
-
React.js
-
{{ 'SitesManager_SiteWithoutDataReactDescription'|translate('', '', '','')|raw }}
- {% endif %}
+ {% for othersInstruction in othersInstructions %}
+
{{ othersInstruction.name }}
+
{{ othersInstruction.othersInstruction|raw }}
+ {% endfor %}
{% if googleAnalyticsImporterMessage is defined and googleAnalyticsImporterMessage is not empty %}
{{ googleAnalyticsImporterMessage|raw }}
diff --git a/plugins/SitesManager/templates/_spa.twig b/plugins/SitesManager/templates/_spa.twig
deleted file mode 100644
index e990fc7372b..00000000000
--- a/plugins/SitesManager/templates/_spa.twig
+++ /dev/null
@@ -1,6 +0,0 @@
-
{{ 'SitesManager_SiteWithoutDataSPADescription'|translate('', '', '', '')|raw }}
-
-
{{ 'SitesManager_SiteWithoutDataCloudflareFollowStepsIntro'|translate }}
-{{ postEvent('Template.embedSPATagManagerTrackingCode') }}
-
-
{{ 'SitesManager_SiteWithoutDataSPAFollowStepCompleted'|translate('','')|raw }}
\ No newline at end of file
diff --git a/plugins/SitesManager/templates/_trackingCodeEmail.twig b/plugins/SitesManager/templates/_trackingCodeEmail.twig
index 097e066f7bb..9241a5195f5 100644
--- a/plugins/SitesManager/templates/_trackingCodeEmail.twig
+++ b/plugins/SitesManager/templates/_trackingCodeEmail.twig
@@ -2,33 +2,33 @@
{{ 'CoreAdminHome_JSTracking_ConsentManagerDetected'|translate(consentManagerName, consentManagerUrl) }}
{% endif %}
-{% if ga3Used %}
+{% if 'GoogleAnalytics3' in trackers %}
{{ 'SitesManager_GADetectedEmail'|translate('Google Analytics 3', 'GA', 'https://matomo.org/faq/how-to/migrate-from-google-analytics-3-to-matomo/')|raw }}
{% endif %}
-{% if ga4Used %}
+{% if 'GoogleAnalytics3' in trackers %}
{{ 'SitesManager_GADetectedEmail'|translate('Google Analytics 4', 'GA', 'https://matomo.org/faq/how-to/migrate-from-google-analytics-4-to-matomo/')|raw }}
{% endif %}
-{% if gtmUsed %}
+{% if 'GoogleTagManager' in trackers %}
{{ 'SitesManager_GTMDetectedEmail'|translate('https://matomo.org/faq/tag-manager/migrating-from-google-tag-manager/')|raw }}
{% endif %}
-{% if cloudflare %}
+{% if 'Cloudflare' in cms %}
{{ 'SitesManager_CloudflareDetectedEmail'|translate('https://matomo.org/faq/new-to-piwik/how-do-i-install-the-matomo-tracking-code-on-my-cloudflare-setup/')|raw }}
{% endif %}
-{% if jsFramework == 'vue' %}
+{% if 'VueJs' in jsFrameworks %}
{{ 'SitesManager_VueDetectedEmail'|translate('vue-matomo', 'https://matomo.org/faq/new-to-piwik/how-do-i-install-the-matomo-tracking-code-on-websites-that-use-vue-js/')|raw }}
{% endif %}
-{% if jsFramework == 'react' %}
+{% if 'ReactJs' in jsFrameworks %}
{{ 'SitesManager_ReactDetectedEmail'|translate('https://matomo.org/faq/new-to-piwik/how-do-i-start-tracking-data-with-matomo-on-websites-that-use-react/')|raw }}
{% endif %}
-{% if consentManagerName or ga3Used or ga4Used or gtmUsed or cloudflare or jsFramework == 'vue' %}
+{% if consentManagerName or 'GoogleAnalytics3' in trackers or 'GoogleAnalytics4' in trackers or 'GoogleTagManager' in trackers or 'Cloudflare' in cms or 'VueJs' in jsFrameworks %}
{{ 'CoreAdminHome_JSTracking_ConsentManagerEmailNote'|translate }}
{% endif %}
diff --git a/plugins/SitesManager/templates/_vueTabInstructions.twig b/plugins/SitesManager/templates/_vueTabInstructions.twig
index 75e45810ee1..d015ac921c6 100644
--- a/plugins/SitesManager/templates/_vueTabInstructions.twig
+++ b/plugins/SitesManager/templates/_vueTabInstructions.twig
@@ -1,3 +1,12 @@
+
+
+ {{ 'SitesManager_VueDetected'|translate('
vue-matomo','
','')|raw }}
+
+
+
+
+
+
{{ 'SitesManager_SiteWithoutDataVueIntro'|translate }}
{{ 'SitesManager_SiteWithoutDataCloudflareFollowStepsIntro'|translate }}
diff --git a/plugins/SitesManager/templates/_wordpressTabInstructions.twig b/plugins/SitesManager/templates/_wordpressTabInstructions.twig
index 8dcad8326b2..e21f8663812 100644
--- a/plugins/SitesManager/templates/_wordpressTabInstructions.twig
+++ b/plugins/SitesManager/templates/_wordpressTabInstructions.twig
@@ -1,3 +1,7 @@
+
+
+
+
A site