Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Live/VisitorProfile.php')
-rw-r--r--plugins/Live/VisitorProfile.php347
1 files changed, 24 insertions, 323 deletions
diff --git a/plugins/Live/VisitorProfile.php b/plugins/Live/VisitorProfile.php
index dcf73413af..f4ea6a660c 100644
--- a/plugins/Live/VisitorProfile.php
+++ b/plugins/Live/VisitorProfile.php
@@ -2,7 +2,7 @@
/**
* Piwik - free/libre analytics platform
*
- * @link http://piwik.org
+ * @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
@@ -11,27 +11,16 @@ namespace Piwik\Plugins\Live;
use Exception;
use Piwik\DataTable;
-use Piwik\Date;
-use Piwik\Metrics\Formatter;
-use Piwik\Piwik;
-use Piwik\Site;
-use Piwik\Plugins\Referrers\API as APIReferrers;
class VisitorProfile
{
const VISITOR_PROFILE_MAX_VISITS_TO_SHOW = 10;
protected $profile = array();
- private $siteSearchKeywords = array();
- private $continents = array();
- private $countries = array();
- private $cities = array();
- private $pageGenerationTimeTotal = 0;
public function __construct($idSite)
{
$this->idSite = $idSite;
- $this->isEcommerceEnabled = Site::isEcommerceEnabledFor($this->idSite);
}
/**
@@ -44,345 +33,57 @@ class VisitorProfile
*/
public function makeVisitorProfile(DataTable $visits, $visitorId, $segment, $numLastVisits)
{
- $this->initVisitorProfile();
+ $visitorDetailsManipulators = Visitor::getAllVisitorDetailsInstances();
+
+ $this->profile['visitorId'] = $visitorId;
+
+ foreach ($visitorDetailsManipulators as $instance) {
+ $instance->initProfile($visits, $this->profile);
+ }
/** @var DataTable\Row $visit */
foreach ($visits->getRows() as $visit) {
- ++$this->profile['totalVisits'];
-
- $this->profile['totalVisitDuration'] += $visit->getColumn('visitDuration');
- $this->profile['totalActions'] += $visit->getColumn('actions');
- $this->profile['totalGoalConversions'] += $visit->getColumn('goalConversions');
+ foreach ($visitorDetailsManipulators as $instance) {
+ $instance->handleProfileVisit($visit, $this->profile);
+ }
- // individual goal conversions are stored in action details
foreach ($visit->getColumn('actionDetails') as $action) {
- $this->handleIfGoalAction($action);
- $this->handleIfEventAction($action);
- $this->handleIfDownloadAction($action);
- $this->handleIfOutlinkAction($action);
- $this->handleIfSiteSearchAction($action);
- $this->handleIfPageViewAction($action);
- $this->handleIfPageGenerationTime($action);
+ foreach ($visitorDetailsManipulators as $instance) {
+ $instance->handleProfileAction($action, $this->profile);
+ }
}
- $this->handleGeoLocation($visit);
}
- $this->handleGeoLocationCountries();
- $this->handleGeoLocationContinents();
- $this->handleSiteSearches();
- $this->handleAveragePageGenerationTime();
-
- $formatter = new Formatter();
- $this->profile['totalVisitDurationPretty'] = $formatter->getPrettyTimeFromSeconds($this->profile['totalVisitDuration'], true);
-
- $this->handleVisitsSummary($visits);
-
// use N most recent visits for last_visits
$visits->deleteRowsOffset($numLastVisits);
$this->profile['lastVisits'] = $visits;
-
- $this->profile['userId'] = $visit->getColumn('userId');
- $this->profile['visitorId'] = $visitorId;
$this->handleAdjacentVisitorIds($visits, $visitorId, $segment);
- if($this->isEcommerceEnabled()) {
- $this->profile['totalEcommerceRevenue'] = $visit->getColumn('totalEcommerceRevenue');
- $this->profile['totalEcommerceConversions'] = $visit->getColumn('totalEcommerceConversions');
- $this->profile['totalEcommerceItems'] = $visit->getColumn('totalEcommerceItems');
- $this->profile['totalAbandonedCartsRevenue'] = $visit->getColumn('totalAbandonedCartsRevenue');
- $this->profile['totalAbandonedCarts'] = $visit->getColumn('totalAbandonedCarts');
- $this->profile['totalAbandonedCartsItems'] = $visit->getColumn('totalAbandonedCartsItems');
+ foreach ($visitorDetailsManipulators as $instance) {
+ $instance->finalizeProfile($visits, $this->profile);
}
return $this->profile;
}
/**
- * Returns a summary for an important visit. Used to describe the first & last visits of a visitor.
- *
- * @param DataTable\Row $visit
- * @return array
- */
- private function getVisitorProfileVisitSummary($visit)
- {
- $today = Date::today();
-
- $serverDate = $visit->getColumn('firstActionTimestamp');
- return array(
- 'date' => $serverDate,
- 'prettyDate' => Date::factory($serverDate)->getLocalized(Date::DATE_FORMAT_LONG),
- 'daysAgo' => (int)Date::secondsToDays($today->getTimestamp() - Date::factory($serverDate)->getTimestamp()),
- 'referrerType' => $visit->getColumn('referrerType'),
- 'referralSummary' => self::getReferrerSummaryForVisit($visit),
- );
- }
-
-
- /**
- * Returns a summary for a visit's referral.
- *
- * @param DataTable\Row $visit
- * @return bool|mixed|string
- */
- public static function getReferrerSummaryForVisit($visit)
- {
- $referrerType = $visit->getColumn('referrerType');
- if ($referrerType === false
- || $referrerType == 'direct'
- ) {
- return Piwik::translate('Referrers_DirectEntry');
- }
-
- if ($referrerType == 'search') {
- $referrerName = $visit->getColumn('referrerName');
-
- $keyword = $visit->getColumn('referrerKeyword');
- if ($keyword !== false
- && $keyword != APIReferrers::getKeywordNotDefinedString()
- ) {
- $referrerName .= ' (' . $keyword . ')';
- }
- return $referrerName;
- }
-
- if ($referrerType == 'campaign') {
-
- $summary = Piwik::translate('Referrers_ColumnCampaign') . ': ' . $visit->getColumn('referrerName');
- $keyword = $visit->getColumn('referrerKeyword');
- if (!empty($keyword)) {
- $summary .= ' - ' . $keyword;
- }
-
- return $summary;
- }
-
- return $visit->getColumn('referrerName');
- }
-
- private function isEcommerceEnabled()
- {
- return $this->isEcommerceEnabled;
- }
-
- /**
- * @param $action
- */
- private function handleIfEventAction($action)
- {
- if ($action['type'] != 'event') {
- return;
- }
- $this->profile['totalEvents']++;
- }
-
- /**
- * @param $action
- */
- private function handleIfDownloadAction($action)
- {
- if ($action['type'] != 'download') {
- return;
- }
- $this->profile['totalDownloads']++;
- }
-
- /**
- * @param $action
- */
- private function handleIfOutlinkAction($action)
- {
- if ($action['type'] != 'outlink') {
- return;
- }
- $this->profile['totalOutlinks']++;
- }
-
- /**
- * @param $action
- */
- private function handleIfPageViewAction($action)
- {
- if ($action['type'] != 'action') {
- return;
- }
- $this->profile['totalPageViews']++;
- }
-
- private function handleIfGoalAction($action)
- {
- if ($action['type'] != 'goal') {
- return;
- }
- $idGoal = $action['goalId'];
- $idGoalKey = 'idgoal=' . $idGoal;
-
- if (!isset($this->profile['totalConversionsByGoal'][$idGoalKey])) {
- $this->profile['totalConversionsByGoal'][$idGoalKey] = 0;
- }
- ++$this->profile['totalConversionsByGoal'][$idGoalKey];
-
- if (!empty($action['revenue'])) {
- if (!isset($this->profile['totalRevenueByGoal'][$idGoalKey])) {
- $this->profile['totalRevenueByGoal'][$idGoalKey] = 0;
- }
- $this->profile['totalRevenueByGoal'][$idGoalKey] += $action['revenue'];
- }
- }
-
- private function handleIfSiteSearchAction($action)
- {
- if (!isset($action['siteSearchKeyword'])) {
- return;
- }
- $keyword = $action['siteSearchKeyword'];
-
- if (!isset($this->siteSearchKeywords[$keyword])) {
- $this->siteSearchKeywords[$keyword] = 0;
- ++$this->profile['totalSearches'];
- }
- ++$this->siteSearchKeywords[$keyword];
- }
-
- private function handleGeoLocation(DataTable\Row $visit)
- {
- // realtime map only checks for latitude
- $hasLatitude = $visit->getColumn('latitude') !== false;
- if ($hasLatitude) {
- $this->profile['hasLatLong'] = true;
- }
-
- $countryCode = $visit->getColumn('countryCode');
- if (!isset($this->countries[$countryCode])) {
- $this->countries[$countryCode] = 0;
- }
- ++$this->countries[$countryCode];
-
- $continentCode = $visit->getColumn('continentCode');
- if (!isset($this->continents[$continentCode])) {
- $this->continents[$continentCode] = 0;
- }
- ++$this->continents[$continentCode];
-
- if ($countryCode && !array_key_exists($countryCode, $this->cities)) {
- $this->cities[$countryCode] = array();
- }
- $city = $visit->getColumn('city');
- if (!empty($city)) {
- $this->cities[$countryCode][] = $city;
- }
- }
-
- private function handleSiteSearches()
- {
- // sort by visit/action
- arsort($this->siteSearchKeywords);
-
- foreach ($this->siteSearchKeywords as $keyword => $searchCount) {
- $this->profile['searches'][] = array('keyword' => $keyword,
- 'searches' => $searchCount);
- }
- }
-
- private function handleGeoLocationContinents()
- {
- // sort by visit/action
- asort($this->continents);
- foreach ($this->continents as $continentCode => $nbVisits) {
- $this->profile['continents'][] = array('continent' => $continentCode,
- 'nb_visits' => $nbVisits,
- 'prettyName' => \Piwik\Plugins\UserCountry\continentTranslate($continentCode));
- }
- }
-
- private function handleGeoLocationCountries()
- {
- // sort by visit/action
- asort($this->countries);
-
- // transform country/continents/search keywords into something that will look good in XML
- $this->profile['countries'] = $this->profile['continents'] = $this->profile['searches'] = array();
-
- foreach ($this->countries as $countryCode => $nbVisits) {
-
- $countryInfo = array('country' => $countryCode,
- 'nb_visits' => $nbVisits,
- 'flag' => \Piwik\Plugins\UserCountry\getFlagFromCode($countryCode),
- 'prettyName' => \Piwik\Plugins\UserCountry\countryTranslate($countryCode));
- if (!empty($this->cities[$countryCode])) {
- $countryInfo['cities'] = array_unique($this->cities[$countryCode]);
- }
- $this->profile['countries'][] = $countryInfo;
- }
- }
-
- private function initVisitorProfile()
- {
- $this->profile['totalVisits'] = 0;
- $this->profile['totalVisitDuration'] = 0;
- $this->profile['totalActions'] = 0;
- $this->profile['totalEvents'] = 0;
- $this->profile['totalOutlinks'] = 0;
- $this->profile['totalDownloads'] = 0;
- $this->profile['totalSearches'] = 0;
- $this->profile['totalPageViews'] = 0;
- $this->profile['totalPageViewsWithTiming'] = 0;
- $this->profile['totalGoalConversions'] = 0;
- $this->profile['totalConversionsByGoal'] = array();
- $this->profile['hasLatLong'] = false;
-
- if ($this->isEcommerceEnabled()) {
- $this->profile['totalEcommerceRevenue'] = 0;
- $this->profile['totalEcommerceConversions'] = 0;
- $this->profile['totalEcommerceItems'] = 0;
- $this->profile['totalAbandonedCarts'] = 0;
- $this->profile['totalAbandonedCartsRevenue'] = 0;
- $this->profile['totalAbandonedCartsItems'] = 0;
- }
- }
-
- private function handleAveragePageGenerationTime()
- {
- if ($this->profile['totalPageViewsWithTiming']) {
- $this->profile['averagePageGenerationTime'] =
- round($this->pageGenerationTimeTotal / (1000 * $this->profile['totalPageViewsWithTiming']), $precision = 3);
- }
- }
-
- private function handleIfPageGenerationTime($action)
- {
- if (isset($action['generationTimeMilliseconds'])) {
- $this->pageGenerationTimeTotal += $action['generationTimeMilliseconds'];
- ++$this->profile['totalPageViewsWithTiming'];
- }
- }
-
- /**
* @param DataTable $visits
- * @param $visitorId
- * @param $segment
+ * @param $visitorId
+ * @param $segment
*/
private function handleAdjacentVisitorIds(DataTable $visits, $visitorId, $segment)
{
// get visitor IDs that are adjacent to this one in log_visit
// TODO: make sure order of visitor ids is not changed if a returning visitor visits while the user is
// looking at the popup.
- $rows = $visits->getRows();
+ $rows = $visits->getRows();
$latestVisitTime = reset($rows)->getColumn('lastActionDateTime');
- $model = new Model();
- $this->profile['nextVisitorId'] = $model->queryAdjacentVisitorId($this->idSite, $visitorId, $latestVisitTime, $segment, $getNext = true);
- $this->profile['previousVisitorId'] = $model->queryAdjacentVisitorId($this->idSite, $visitorId, $latestVisitTime, $segment, $getNext = false);
- }
-
- /**
- * @param DataTable $visits
- */
- private function handleVisitsSummary(DataTable $visits)
- {
- $rows = $visits->getRows();
- $this->profile['firstVisit'] = $this->getVisitorProfileVisitSummary(end($rows));
- $this->profile['lastVisit'] = $this->getVisitorProfileVisitSummary(reset($rows));
- $this->profile['visitsAggregated'] = count($rows);
+ $model = new Model();
+ $this->profile['nextVisitorId'] = $model->queryAdjacentVisitorId($this->idSite, $visitorId,
+ $latestVisitTime, $segment, $getNext = true);
+ $this->profile['previousVisitorId'] = $model->queryAdjacentVisitorId($this->idSite, $visitorId,
+ $latestVisitTime, $segment, $getNext = false);
}
} \ No newline at end of file