Download plugins/CoreHome/Tracker/VisitRequestProcessor.php from Leon4gr45/matomo: direct link, hf CLI and curl.
- Browser
- Download file 10.5 kB
-
https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/CoreHome/Tracker/VisitRequestProcessor.php
- Command line
-
hf download hf://spaces/Leon4gr45/matomo/plugins/CoreHome/Tracker/VisitRequestProcessor.php
-
curl -L -o VisitRequestProcessor.php https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/CoreHome/Tracker/VisitRequestProcessor.php
10.5 kB
| /** | |
| * Matomo - free/libre analytics platform | |
| * | |
| * @link https://matomo.org | |
| * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later | |
| */ | |
| namespace Piwik\Plugins\CoreHome\Tracker; | |
| use Piwik\Common; | |
| use Piwik\Date; | |
| use Piwik\EventDispatcher; | |
| use Piwik\Exception\UnexpectedWebsiteFoundException; | |
| use Piwik\Tracker\Cache; | |
| use Piwik\Tracker\Request; | |
| use Piwik\Tracker\RequestProcessor; | |
| use Piwik\Tracker\Settings; | |
| use Piwik\Tracker\TrackerConfig; | |
| use Piwik\Tracker\Visit\VisitProperties; | |
| use Piwik\Tracker\VisitExcluded; | |
| use Piwik\Tracker\VisitorRecognizer; | |
| use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig; | |
| /** | |
| * Encapsulates core tracking logic related to visits. | |
| * | |
| * ## Request Metadata | |
| * | |
| * This RequestProcessor exposes the following metadata for the **CoreHome** plugin: | |
| * | |
| * * **visitorId**: A hash that identifies the current visitor being tracked. This value is | |
| * calculated using the Piwik\Tracker\Settings::getConfigId() method. | |
| * | |
| * Set in `processRequestParams()`. | |
| * | |
| * * **isVisitorKnown**: True if the current visitor has visited the site before. False if | |
| * otherwise. | |
| * | |
| * Set in `processRequestParams()`. | |
| * | |
| * * **isNewVisit**: True if the current action is the start of a new visit, false if it | |
| * is part of an ongoing visit. | |
| * | |
| * Set in `processRequestParams()`. Other RequestProcessors can override | |
| * this value to force a new visit or stop a new visit. | |
| * | |
| * * **visitorNotFoundInDb**: True if the current visit could not be updated. | |
| * | |
| * Set by the Visit object. | |
| */ | |
| class VisitRequestProcessor extends RequestProcessor | |
| { | |
| // TODO: much of the logic in this class should be moved to new service class | |
| /** | |
| * @var EventDispatcher | |
| */ | |
| private $eventDispatcher; | |
| /** | |
| * @var VisitorRecognizer | |
| */ | |
| private $visitorRecognizer; | |
| /** | |
| * @var Settings | |
| */ | |
| private $userSettings; | |
| /** | |
| * @var int | |
| */ | |
| private $visitStandardLength; | |
| /** | |
| * Forces all requests to result in new visits. For debugging only. | |
| * | |
| * @var int | |
| */ | |
| private $trackerAlwaysNewVisitor; | |
| public function __construct( | |
| EventDispatcher $eventDispatcher, | |
| VisitorRecognizer $visitorRecognizer, | |
| Settings $userSettings, | |
| $visitStandardLength, | |
| $trackerAlwaysNewVisitor | |
| ) { | |
| $this->eventDispatcher = $eventDispatcher; | |
| $this->visitorRecognizer = $visitorRecognizer; | |
| $this->userSettings = $userSettings; | |
| $this->visitStandardLength = $visitStandardLength; | |
| $this->trackerAlwaysNewVisitor = $trackerAlwaysNewVisitor; | |
| } | |
| public function processRequestParams(VisitProperties $visitProperties, Request $request) | |
| { | |
| // the IP is needed by isExcluded() and GoalManager->recordGoals() | |
| $visitProperties->setProperty('location_ip', $request->getIp()); | |
| $excluded = new VisitExcluded($request); | |
| $isExcluded = $excluded->isExcluded(); | |
| $request->setMetadata('CoreHome', 'isVisitExcluded', $isExcluded); | |
| if ($isExcluded) { | |
| return true; | |
| } | |
| $privacyConfig = new PrivacyManagerConfig($request->getIdSiteIfExists()); | |
| if ($privacyConfig->randomizeConfigId) { | |
| // always new visit when randomising config id | |
| $request->setMetadata('CoreHome', 'visitorId', $this->userSettings->getRandomConfigId()); | |
| $request->setMetadata('CoreHome', 'isVisitorKnown', false); | |
| $request->setMetadata('CoreHome', 'isNewVisit', true); | |
| $request->setMetadata('CoreHome', 'lastKnownVisit', false); | |
| return false; | |
| } | |
| $ip = $request->getIpString(); | |
| if ($privacyConfig->useAnonymizedIpForVisitEnrichment) { | |
| $ip = $visitProperties->getProperty('location_ip'); | |
| } | |
| // visitor recognition | |
| $visitorId = $this->userSettings->getConfigId($request, $ip); | |
| $request->setMetadata('CoreHome', 'visitorId', $visitorId); | |
| $isKnown = $this->visitorRecognizer->findKnownVisitor($visitorId, $visitProperties, $request); | |
| $request->setMetadata('CoreHome', 'isVisitorKnown', $isKnown); | |
| $isNewVisit = $this->isVisitNew($visitProperties, $request, $this->visitorRecognizer->getLastKnownVisit()); | |
| $request->setMetadata('CoreHome', 'isNewVisit', $isNewVisit); | |
| $request->setMetadata('CoreHome', 'lastKnownVisit', $this->visitorRecognizer->getLastKnownVisit()); | |
| if (!$isNewVisit) { // only copy over known visitor's information, if this is for an ongoing visit | |
| $this->visitorRecognizer->updateVisitPropertiesFromLastVisitRow($visitProperties); | |
| } | |
| return false; | |
| } | |
| public function afterRequestProcessed(VisitProperties $visitProperties, Request $request) | |
| { | |
| $ip = $visitProperties->getProperty('location_ip'); | |
| /** | |
| * Triggered after visits are tested for exclusion so plugins can modify the IP address | |
| * persisted with a visit. | |
| * | |
| * This event is primarily used by the **PrivacyManager** plugin to anonymize IP addresses. | |
| * | |
| * @param string &$ip The visitor's IP address. | |
| * @param int $idSite The site ID we're tracking the visit for. | |
| */ | |
| $this->eventDispatcher->postEvent('Tracker.setVisitorIp', [&$ip, (int) $request->getIdSiteIfExists()]); | |
| $visitProperties->setProperty('location_ip', $ip); | |
| return false; | |
| } | |
| /** | |
| * Determines if the current action should be treated as the start of a new visit or | |
| * an action in an existing visit. | |
| * | |
| * Note: public only for tests. | |
| * | |
| * @param VisitProperties $visitProperties The current visit/visitor information. | |
| * @return bool | |
| */ | |
| public function isVisitNew(VisitProperties $visitProperties, Request $request, $lastKnownVisit) | |
| { | |
| $isKnown = $request->getMetadata('CoreHome', 'isVisitorKnown'); | |
| if (!$isKnown) { | |
| return true; | |
| } | |
| $isNewVisitForced = $request->getParam('new_visit'); | |
| $isNewVisitForced = !empty($isNewVisitForced); | |
| if ($isNewVisitForced) { | |
| Common::printDebug("-> New visit forced: &new_visit=1 in request"); | |
| return true; | |
| } | |
| if ($this->trackerAlwaysNewVisitor) { | |
| Common::printDebug("-> New visit forced: Debug.tracker_always_new_visitor = 1 in config.ini.php"); | |
| return true; | |
| } | |
| $isLastActionInTheSameVisit = $this->isLastActionInTheSameVisit($visitProperties, $request, $lastKnownVisit); | |
| if (!$isLastActionInTheSameVisit) { | |
| Common::printDebug("Visitor detected, but last action was more than 30 minutes ago..."); | |
| return true; | |
| } | |
| $wasLastActionYesterday = $this->wasLastActionNotToday($visitProperties, $request, $lastKnownVisit); | |
| $forceNewVisitAtMidnight = TrackerConfig::getBoolConfigValue('create_new_visit_after_midnight', false, $request->getIdSiteIfExists()); | |
| if ($wasLastActionYesterday && $forceNewVisitAtMidnight) { | |
| Common::printDebug("Visitor detected, but last action was yesterday..."); | |
| return true; | |
| } | |
| if (!$this->lastUserIdWasSetAndDoesMatch($visitProperties, $request)) { | |
| Common::printDebug("Visitor detected, but last user_id does not match..."); | |
| return true; | |
| } | |
| return false; | |
| } | |
| /** | |
| * Returns true if the last action was done within the standard visit length. | |
| * @return bool | |
| */ | |
| protected function isLastActionInTheSameVisit(VisitProperties $visitProperties, Request $request, $lastKnownVisit) | |
| { | |
| $lastActionTime = $this->getLastKnownActionTime($visitProperties, $lastKnownVisit); | |
| return isset($lastActionTime) | |
| && false !== $lastActionTime | |
| && ($lastActionTime > ($request->getCurrentTimestamp() - $this->visitStandardLength)); | |
| } | |
| /** | |
| * Returns true if the last action was not today. | |
| * @return bool | |
| */ | |
| private function wasLastActionNotToday(VisitProperties $visitProperties, Request $request, $lastKnownVisit) | |
| { | |
| $lastActionTime = $this->getLastKnownActionTime($visitProperties, $lastKnownVisit); | |
| if (empty($lastActionTime)) { | |
| return false; | |
| } | |
| $idSite = $request->getIdSite(); | |
| $timezone = $this->getTimezoneForSite($idSite); | |
| if (empty($timezone)) { | |
| throw new UnexpectedWebsiteFoundException('An unexpected website was found, check idSite in the request'); | |
| } | |
| $date = Date::factory((int)$lastActionTime, $timezone); | |
| $now = $request->getCurrentTimestamp(); | |
| $now = Date::factory((int)$now, $timezone); | |
| return $date->toString() !== $now->toString(); | |
| } | |
| private function getTimezoneForSite($idSite) // TODO: duplicate function in Visit | |
| { | |
| try { | |
| $site = Cache::getCacheWebsiteAttributes($idSite); | |
| } catch (UnexpectedWebsiteFoundException $e) { | |
| return null; | |
| } | |
| if (!empty($site['timezone'])) { | |
| return $site['timezone']; | |
| } | |
| return null; | |
| } | |
| /** | |
| * Returns the last action time for the last recorded visit of this visitor, or if the visitor is new, | |
| * the current request's timestamp. | |
| * | |
| * @param $lastKnownVisit | |
| * @return false|int|mixed | |
| */ | |
| private function getLastKnownActionTime(VisitProperties $visitProperties, $lastKnownVisit) | |
| { | |
| if (isset($lastKnownVisit['visit_last_action_time'])) { | |
| return strtotime($lastKnownVisit['visit_last_action_time']); | |
| } | |
| return $visitProperties->getProperty('visit_last_action_time'); | |
| } | |
| /** | |
| * Returns true if the last user_id did not change. | |
| * @return bool | |
| */ | |
| protected function lastUserIdWasSetAndDoesMatch(VisitProperties $visitProperties, Request $request) | |
| { | |
| $lastUserId = $visitProperties->getProperty('user_id'); | |
| if (empty($lastUserId)) { | |
| return true; | |
| } | |
| $currentUserId = $request->getForcedUserId(); | |
| if (empty($currentUserId)) { | |
| return true; | |
| } | |
| return $lastUserId === $currentUserId; | |
| } | |
| } | |