File: D:/web/matomo.vdk/plugins/BotTracking/BotTracking.php
<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
declare(strict_types=1);
namespace Piwik\Plugins\BotTracking;
use Piwik\Date;
use Piwik\Plugin;
use Piwik\Plugins\BotTracking\Dao\BotRequestsDao;
use Piwik\Plugins\SitesManager\API;
use Piwik\Plugins\BotTracking\Metrics as BotMetrics;
use Piwik\Tracker\Request;
/**
* BotTracking Plugin
*
* Tracks AI assistant and bot interactions without creating visits.
* Stores telemetry data in dedicated tables for analysis of bot behavior
* and system performance.
*/
class BotTracking extends Plugin
{
/**
* @return bool
*/
public function isTrackerPlugin()
{
return true;
}
/**
* @return array<string, string>
*/
public function registerEvents(): array
{
return [
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
'PrivacyManager.deleteLogsOlderThan' => 'deleteLogsOlderThan',
'PrivacyManager.deleteDataSubjectsForDeletedSites' => 'deleteDataSubjectsForDeletedSites',
'Tracker.isBotRequest' => 'isBotRequest',
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
'Metrics.getEvolutionUnit' => 'getEvolutionUnit',
'Metrics.getDefaultMetricTranslations' => 'addMetricTranslations',
'Metrics.getDefaultMetricDocumentationTranslations' => 'addMetricDocumentationTranslations',
'Metrics.getDefaultMetricSemanticTypes' => 'addMetricSemanticTypes',
];
}
/**
* @return void
*/
public function install()
{
(new BotRequestsDao())->createTable();
}
/**
* @return void
*/
public function uninstall()
{
(new BotRequestsDao())->dropTable();
}
public function deleteLogsOlderThan(Date $dateUpperLimit): void
{
(new BotRequestsDao())->deleteOldRecords($dateUpperLimit);
}
/**
* @param array<string, int> $result
*/
public function deleteDataSubjectsForDeletedSites(array &$result): void
{
$allExistingIdSites = API::getInstance()->getAllSitesId();
$allExistingIdSites = array_map('intval', $allExistingIdSites);
$maxIdSite = max($allExistingIdSites);
if (empty($maxIdSite)) {
return;
}
$dao = new BotRequestsDao();
$idSitesInTable = $dao->getDistinctIdSitesInTable($maxIdSite);
$idSitesNoLongerExisting = array_diff($idSitesInTable, $allExistingIdSites);
if (count($idSitesNoLongerExisting) > 0) {
$result[$dao::getTableName()] = $dao->deleteRecordsForIdSites($idSitesNoLongerExisting);
}
}
/**
* @todo Remove, once Device Detector is able to detect all known ai bots
*/
public function isBotRequest(bool &$isBot, Request $request): void
{
$botDetector = new BotDetector($request->getUserAgent());
if ($botDetector->isBot()) {
$isBot = true;
}
}
public function getEvolutionUnit(?string &$unit, string $column): void
{
if ($column === Metrics::METRIC_AI_CHATBOTS_CLICK_THROUGH_RATE) {
$unit = '%';
}
}
/**
* @param array<string, string> $translations
*/
public function addMetricTranslations(array &$translations): void
{
$translations = array_merge($translations, BotMetrics::getMetricTranslations());
}
/**
* @param array<string, string> $translations
*/
public function addMetricDocumentationTranslations(array &$translations): void
{
$translations = array_merge($translations, BotMetrics::getMetricDocumentation());
}
/**
* @param array<string|int, string> $types
*/
public function addMetricSemanticTypes(array &$types): void
{
$types = array_merge($types, BotMetrics::getMetricSemanticTypes());
}
public function getClientSideTranslationKeys(&$translationKeys)
{
$translationKeys[] = 'BotTracking_DetectingYourSite';
$translationKeys[] = 'BotTracking_SiteWithoutDataBackToMatomo';
$translationKeys[] = 'BotTracking_SiteWithoutDataChooseTrackingMethod';
$translationKeys[] = 'BotTracking_SiteWithoutDataChooseTrackingMethodPreamble1';
$translationKeys[] = 'BotTracking_SiteWithoutDataChooseTrackingMethodPreamble2';
$translationKeys[] = 'BotTracking_SiteWithoutDataInstallWithX';
$translationKeys[] = 'BotTracking_SiteWithoutDataNotYetReady';
$translationKeys[] = 'BotTracking_SiteWithoutDataOtherInstallMethods';
$translationKeys[] = 'BotTracking_SiteWithoutDataOtherInstallMethodsIntro';
$translationKeys[] = 'BotTracking_SiteWithoutDataInstallWithXRecommendation';
$translationKeys[] = 'BotTracking_SiteWithoutDataRecommendationText';
$translationKeys[] = 'General_ErrorRequest';
$translationKeys[] = 'General_Refresh';
$translationKeys[] = 'Mobile_NavigationBack';
}
public function getStylesheetFiles(&$stylesheets)
{
$stylesheets[] = "plugins/BotTracking/stylesheets/BotTracking.less";
}
}