Sh3ll
OdayForums


Server : LiteSpeed
System : Linux premium84.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64
User : claqxcrl ( 523)
PHP Version : 8.1.32
Disable Function : NONE
Directory :  /home/claqxcrl/anfangola.com/wp-content/plugins/matomo/app/plugins/Actions/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/claqxcrl/anfangola.com/wp-content/plugins/matomo/app/plugins/Actions/VisitorDetails.php
<?php

/**
 * Matomo - free/libre analytics platform
 *
 * @link    https://matomo.org
 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
 *
 */
namespace Piwik\Plugins\Actions;

use Piwik\Common;
use Piwik\Date;
use Piwik\Metrics\Formatter;
use Piwik\Piwik;
use Piwik\Plugin;
use Piwik\Plugins\Live\VisitorDetailsAbstract;
use Piwik\Site;
use Piwik\Tracker\Action;
use Piwik\Tracker\PageUrl;
class VisitorDetails extends VisitorDetailsAbstract
{
    public function extendVisitorDetails(&$visitor)
    {
        $visitor['searches'] = $this->details['visit_total_searches'];
        $visitor['actions'] = $this->details['visit_total_actions'];
        $visitor['interactions'] = $this->details['visit_total_interactions'];
    }
    public function provideActionsForVisitIds(&$actions, $visitIds)
    {
        $actionDetails = $this->queryActionsForVisits($visitIds);
        // use while / array_shift combination instead of foreach to save memory
        while (is_array($actionDetails) && count($actionDetails)) {
            $action = array_shift($actionDetails);
            $idVisit = $action['idvisit'];
            unset($action['idvisit']);
            $actions[$idVisit][] = $action;
        }
    }
    public function provideActionsForVisit(&$actions, $visitorDetails)
    {
        $actionDetails = $actions;
        $formatter = new Formatter();
        // Enrich with time spent per action
        $nextActionId = 0;
        foreach ($actionDetails as $idx => &$action) {
            if ($idx < $nextActionId || !$this->isPageView($action)) {
                unset($action['timeSpentRef']);
                continue;
                // skip to next page view
            }
            $action['timeSpent'] = 0;
            // search for next action with timeSpentRef
            $nextActionId = $idx;
            $nextAction = null;
            do {
                $nextActionId++;
                $nextAction = isset($actionDetails[$nextActionId]) ? $actionDetails[$nextActionId] : null;
                if (is_null($nextAction)) {
                    // Last action of a visit.
                    // By default, Matomo does not know how long the user stayed on the page
                    // If enableHeartBeatTimer() is used in piwik.js then we can find the accurate time on page for the last pageview
                    $visitTotalTime = $visitorDetails['visitDuration'];
                    $timeOfLastAction = Date::factory($action['serverTimePretty'])->getTimestamp();
                    $timeSpentOnAllActionsApartFromLastOne = $timeOfLastAction - $visitorDetails['firstActionTimestamp'];
                    $timeSpentOnPage = $visitTotalTime - $timeSpentOnAllActionsApartFromLastOne;
                    // Safe net, we assume the time is correct when it's more than 10 seconds
                    if ($timeSpentOnPage > 10) {
                        $action['timeSpent'] = $timeSpentOnPage;
                    }
                    break;
                }
                if (!array_key_exists('timeSpentRef', $nextAction)) {
                    continue;
                }
                // Set the time spent for this action (which is the timeSpentRef of the next action)
                if ($nextAction) {
                    $action['timeSpent'] += $nextAction['timeSpentRef'] ?? 0;
                }
                // sum spent time until next page view
                if ($this->isPageView($nextAction)) {
                    break;
                }
            } while (isset($actionDetails[$nextActionId]));
            if (isset($action['timeSpent'])) {
                $action['timeSpentPretty'] = $formatter->getPrettyTimeFromSeconds($action['timeSpent'], true);
            }
            unset($action['timeSpentRef']);
        }
        $actions = $actionDetails;
    }
    private function shouldHandleAction($action)
    {
        $actionTypesToHandle = array(Action::TYPE_PAGE_URL, Action::TYPE_PAGE_TITLE, Action::TYPE_SITE_SEARCH, Action::TYPE_EVENT, Action::TYPE_OUTLINK, Action::TYPE_DOWNLOAD);
        return in_array($action['type'], $actionTypesToHandle) || !empty($action['eventType']);
    }
    private function isPageView($action)
    {
        $pageViewTypes = array(Action::TYPE_PAGE_URL, Action::TYPE_PAGE_TITLE);
        return in_array($action['type'], $pageViewTypes);
    }
    public function extendActionDetails(&$action, $nextAction, $visitorDetails)
    {
        $formatter = new Formatter();
        if ($action['type'] == Action::TYPE_SITE_SEARCH) {
            // Handle Site Search
            $action['siteSearchKeyword'] = $action['pageTitle'];
            $action['siteSearchCategory'] = $action['search_cat'];
            $action['siteSearchCount'] = $action['search_count'];
            unset($action['pageTitle']);
        }
        unset($action['search_cat']);
        unset($action['search_count']);
        // Generation time
        if ($this->shouldHandleAction($action) && empty($action['eventType']) && isset($action['custom_float']) && $action['custom_float'] > 0) {
            $action['generationTimeMilliseconds'] = $action['custom_float'];
            $action['generationTime'] = $formatter->getPrettyTimeFromSeconds($action['custom_float'] / 1000, true);
            unset($action['custom_float']);
        }
        if (array_key_exists('custom_float', $action) && is_null($action['custom_float'])) {
            unset($action['custom_float']);
        }
        if (!array_key_exists('pageLoadTime', $action) || $action['pageLoadTime'] <= 0) {
            unset($action['pageLoadTime']);
        } else {
            $action['pageLoadTimeMilliseconds'] = $action['pageLoadTime'];
            $action['pageLoadTime'] = $formatter->getPrettyTimeFromSeconds($action['pageLoadTime'] / 1000, true);
        }
        if (array_key_exists('pageview_position', $action)) {
            $action['pageviewPosition'] = $action['pageview_position'];
            unset($action['pageview_position']);
        }
        // Reconstruct url from prefix
        if (array_key_exists('url', $action) && array_key_exists('url_prefix', $action)) {
            if ($action['url'] && stripos($action['url'], 'http://') !== 0 && stripos($action['url'], 'https://') !== 0) {
                $url = PageUrl::reconstructNormalizedUrl($action['url'], $action['url_prefix']);
                $url = Common::unsanitizeInputValue($url);
                $action['url'] = $url;
            }
            unset($action['url_prefix']);
        }
        if (!empty($action['url']) && strpos($action['url'], 'http://') === 0) {
            $host = parse_url($action['url'], PHP_URL_HOST);
            if ($host && PageUrl::shouldUseHttpsHost($visitorDetails['idSite'], $host)) {
                $action['url'] = 'https://' . mb_substr($action['url'], 7);
            }
        }
        switch ($action['type']) {
            case 'goal':
                $action['icon'] = 'plugins/Morpheus/images/goal.png';
                $action['iconSVG'] = 'plugins/Morpheus/images/goal.svg';
                $action['title'] = Piwik::translate('Goals_GoalConversion');
                $action['subtitle'] = $action['goalName'];
                if (!empty($action['revenue'])) {
                    $action['subtitle'] .= ' (' . Piwik::translate('Goals_NRevenue', $formatter->getPrettyMoney($action['revenue'], $visitorDetails['idSite'])) . ')';
                }
                break;
            case Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER:
            case Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART:
                $action['icon'] = 'plugins/Morpheus/images/' . $action['type'] . '.png';
                $action['iconSVG'] = 'plugins/Morpheus/images/' . $action['type'] . '.svg';
                if ($action['type'] == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
                    $action['title'] = Piwik::translate('CoreHome_VisitStatusOrdered') . ' (' . $action['orderId'] . ')';
                } else {
                    $action['title'] = Piwik::translate('Goals_AbandonedCart');
                }
                $itemNames = implode(', ', array_column($action['itemDetails'], 'itemName'));
                $action['subtitle'] = Piwik::translate('Goals_NRevenue', $formatter->getPrettyMoney($action['revenue'], $visitorDetails['idSite']));
                $action['subtitle'] .= ' - ' . Piwik::translate('Goals_NItems', $action['items']) . ': ' . $itemNames . ')';
                break;
            case Action::TYPE_CONTENT:
                if (!empty($action['contentInteraction'])) {
                    $action['icon'] = 'plugins/Morpheus/images/contentinteraction.png';
                    $action['iconSVG'] = 'plugins/Morpheus/images/contentinteraction.svg';
                    $action['title'] = Piwik::translate('Contents_ContentInteraction') . ' (' . $action['contentInteraction'] . ')';
                } else {
                    $action['icon'] = 'plugins/Morpheus/images/contentimpression.png';
                    $action['iconSVG'] = 'plugins/Morpheus/images/contentimpression.svg';
                    $action['title'] = Piwik::translate('Contents_ContentImpression');
                }
                $action['subtitle'] = $action['contentName'];
                if (!empty($action['contentPiece'])) {
                    $action['subtitle'] .= ' - ' . $action['contentPiece'];
                }
                break;
            case Action::TYPE_DOWNLOAD:
                $action['type'] = 'download';
                $action['icon'] = 'plugins/Morpheus/images/download.png';
                $action['iconSVG'] = 'plugins/Morpheus/images/download.svg';
                $action['title'] = Piwik::translate('General_Download');
                $action['subtitle'] = $action['url'];
                break;
            case Action::TYPE_OUTLINK:
                $action['type'] = 'outlink';
                $action['icon'] = 'plugins/Morpheus/images/link.png';
                $action['iconSVG'] = 'plugins/Morpheus/images/link.svg';
                $action['title'] = Piwik::translate('General_Outlink');
                $action['subtitle'] = $action['url'];
                break;
            case Action::TYPE_SITE_SEARCH:
                $action['type'] = 'search';
                $action['icon'] = 'plugins/Morpheus/images/search.png';
                $action['iconSVG'] = 'plugins/Morpheus/images/search.svg';
                $action['title'] = Piwik::translate('Actions_SubmenuSitesearch');
                $action['subtitle'] = $action['siteSearchKeyword'];
                if (!empty($action['siteSearchCategory'])) {
                    $action['subtitle'] .= ' - ' . Piwik::translate('Actions_ColumnSearchCategory') . ': ' . $action['siteSearchCategory'];
                }
                if (!empty($action['siteSearchCount'])) {
                    $action['subtitle'] .= ' - ' . Piwik::translate('Actions_ColumnSearchResultsCount') . ': ' . $action['siteSearchCount'];
                }
                break;
            case Action::TYPE_PAGE_URL:
            case Action::TYPE_PAGE_TITLE:
            case '':
                if (!isset($action['title'])) {
                    $action['title'] = $action['pageTitle'];
                    $action['subtitle'] = $action['url'];
                }
                $action['type'] = 'action';
                $action['icon'] = '';
                $action['iconSVG'] = 'plugins/Morpheus/images/action.svg';
                break;
        }
        // Convert datetimes to the site timezone
        $dateTimeVisit = Date::factory($action['serverTimePretty'], Site::getTimezoneFor($visitorDetails['idSite']));
        $action['serverTimePretty'] = $dateTimeVisit->getLocalized(Date::DATETIME_FORMAT_SHORT);
        $action['timestamp'] = $dateTimeVisit->getTimestamp();
        unset($action['idlink_va']);
    }
    /**
     * @param $idVisit
     * @return array
     * @throws \Exception
     */
    protected function queryActionsForVisits($idVisits)
    {
        $customFields = array();
        $customJoins = array();
        Piwik::postEvent('Actions.getCustomActionDimensionFieldsAndJoins', array(&$customFields, &$customJoins));
        $customFields = array_filter($customFields);
        array_unshift($customFields, '');
        // add empty element at first
        $customActionDimensionFields = implode(', ', $customFields);
        // The second join is a LEFT join to allow returning records that don't have a matching page title
        // eg. Downloads, Outlinks. For these, idaction_name is set to 0
        $pagePerformanceSelect = '';
        if (Plugin\Manager::getInstance()->isPluginActivated('PagePerformance')) {
            $pagePerformanceSelect = '( log_link_visit_action.time_network +
					log_link_visit_action.time_server +
					log_link_visit_action.time_transfer +
					log_link_visit_action.time_dom_completion +
					log_link_visit_action.time_dom_processing +
					log_link_visit_action.time_on_load ) AS pageLoadTime,';
        }
        $sql = "\n\t\t\t\tSELECT\n\t\t\t\t\tlog_link_visit_action.idvisit,\n\t\t\t\t\tCOALESCE(log_action.type, log_action_title.type) AS type,\n\t\t\t\t\tlog_action.name AS url,\n\t\t\t\t\tlog_action.url_prefix,\n\t\t\t\t\tlog_action_title.name AS pageTitle,\n\t\t\t\t\tlog_action.idaction AS pageIdAction,\n\t\t\t\t\tlog_link_visit_action.idpageview,\n\t\t\t\t\tlog_link_visit_action.idlink_va,\n\t\t\t\t\tlog_link_visit_action.server_time as serverTimePretty,\n\t\t\t\t\tlog_link_visit_action.time_spent_ref_action as timeSpentRef,\n\t\t\t\t\tlog_link_visit_action.idlink_va AS pageId,\n\t\t\t\t\tlog_link_visit_action.custom_float,\n\t\t\t\t\t{$pagePerformanceSelect}\n\t\t\t\t\tlog_link_visit_action.pageview_position,\n\t\t\t\t\tlog_link_visit_action.search_cat,\n\t\t\t\t\tlog_link_visit_action.search_count\n\t\t\t\t\t" . $customActionDimensionFields . "\n\t\t\t\tFROM " . Common::prefixTable('log_link_visit_action') . " AS log_link_visit_action\n\t\t\t\t\tLEFT JOIN " . Common::prefixTable('log_action') . " AS log_action\n\t\t\t\t\tON  log_link_visit_action.idaction_url = log_action.idaction\n\t\t\t\t\tLEFT JOIN " . Common::prefixTable('log_action') . " AS log_action_title\n\t\t\t\t\tON  log_link_visit_action.idaction_name = log_action_title.idaction\n\t\t\t\t\t" . implode(" ", $customJoins) . "\n\t\t\t\tWHERE log_link_visit_action.idvisit IN ('" . implode("','", $idVisits) . "')\n\t\t\t\tORDER BY log_link_visit_action.idvisit, server_time ASC\n\t\t\t\t ";
        $actionDetails = $this->getDb()->fetchAll($sql);
        return $actionDetails;
    }
    private $visitedPageUrls = array();
    private $siteSearchKeywords = array();
    private $pageGenerationTimeTotal = 0;
    private $pageLoadTimeTotal = 0;
    public function initProfile($visits, &$profile)
    {
        $this->visitedPageUrls = array();
        $this->siteSearchKeywords = array();
        $this->pageGenerationTimeTotal = 0;
        $this->pageLoadTimeTotal = 0;
        $profile['totalActions'] = 0;
        $profile['totalOutlinks'] = 0;
        $profile['totalDownloads'] = 0;
        $profile['totalSearches'] = 0;
        $profile['totalPageViews'] = 0;
        $profile['totalUniquePageViews'] = 0;
        $profile['totalRevisitedPages'] = 0;
        $profile['totalPageViewsWithTiming'] = 0;
        $profile['totalPageViewsWithLoadTime'] = 0;
        $profile['searches'] = array();
    }
    public function handleProfileVisit($visit, &$profile)
    {
        $profile['totalActions'] += $visit->getColumn('actions');
    }
    public function handleProfileAction($action, &$profile)
    {
        $this->handleIfDownloadAction($action, $profile);
        $this->handleIfOutlinkAction($action, $profile);
        $this->handleIfSiteSearchAction($action, $profile);
        $this->handleIfPageViewAction($action, $profile);
        $this->handleIfPageGenerationTime($action, $profile);
        $this->handleIfPageLoadTime($action, $profile);
    }
    public function finalizeProfile($visits, &$profile)
    {
        $profile['visitedPages'] = [];
        foreach ($this->visitedPageUrls as $visitedPageUrl => $count) {
            $profile['visitedPages'][] = ['url' => $visitedPageUrl, 'count' => $count];
        }
        usort($profile['visitedPages'], function ($a, $b) {
            if ($a['count'] == $b['count']) {
                return strcmp($a['url'], $b['url']);
            }
            return $a['count'] > $b['count'] ? -1 : 1;
        });
        $this->handleSiteSearches($profile);
        $this->handleAveragePageGenerationTime($profile);
        $this->handleAveragePageLoadTime($profile);
    }
    /**
     * @param $action
     */
    private function handleIfDownloadAction($action, &$profile)
    {
        if ($action['type'] != 'download') {
            return;
        }
        $profile['totalDownloads']++;
    }
    /**
     * @param $action
     */
    private function handleIfOutlinkAction($action, &$profile)
    {
        if ($action['type'] != 'outlink') {
            return;
        }
        $profile['totalOutlinks']++;
    }
    /**
     * @param $action
     */
    private function handleIfPageViewAction($action, &$profile)
    {
        if ($action['type'] != 'action') {
            return;
        }
        $profile['totalPageViews']++;
        $pageUrl = $action['url'];
        if (!empty($pageUrl)) {
            if (!array_key_exists($pageUrl, $this->visitedPageUrls)) {
                $this->visitedPageUrls[$pageUrl] = 0;
                $profile['totalUniquePageViews']++;
            }
            $this->visitedPageUrls[$pageUrl]++;
            if ($this->visitedPageUrls[$pageUrl] == 2) {
                $profile['totalRevisitedPages']++;
            }
        }
    }
    private function handleIfSiteSearchAction($action, &$profile)
    {
        if (!isset($action['siteSearchKeyword'])) {
            return;
        }
        $keyword = $action['siteSearchKeyword'];
        if (!isset($this->siteSearchKeywords[$keyword])) {
            $this->siteSearchKeywords[$keyword] = 0;
            ++$profile['totalSearches'];
        }
        ++$this->siteSearchKeywords[$keyword];
    }
    private function handleSiteSearches(&$profile)
    {
        // sort by visit/action
        arsort($this->siteSearchKeywords);
        foreach ($this->siteSearchKeywords as $keyword => $searchCount) {
            $profile['searches'][] = array('keyword' => $keyword, 'searches' => $searchCount);
        }
    }
    private function handleIfPageGenerationTime($action, &$profile)
    {
        if (isset($action['generationTimeMilliseconds'])) {
            $this->pageGenerationTimeTotal += $action['generationTimeMilliseconds'];
            ++$profile['totalPageViewsWithTiming'];
        }
    }
    private function handleAveragePageGenerationTime(&$profile)
    {
        if ($profile['totalPageViewsWithTiming']) {
            $profile['averagePageGenerationTime'] = round($this->pageGenerationTimeTotal / (1000 * $profile['totalPageViewsWithTiming']), $precision = 3);
        }
    }
    private function handleIfPageLoadTime($action, &$profile)
    {
        if (isset($action['pageLoadTimeMilliseconds'])) {
            $this->pageLoadTimeTotal += $action['pageLoadTimeMilliseconds'];
            ++$profile['totalPageViewsWithLoadTime'];
        }
    }
    private function handleAveragePageLoadTime(&$profile)
    {
        if ($profile['totalPageViewsWithLoadTime']) {
            $profile['averagePageLoadTime'] = round($this->pageLoadTimeTotal / (1000 * $profile['totalPageViewsWithLoadTime']), $precision = 3);
        }
    }
}

ZeroDay Forums Mini