PDF rausgenommen
This commit is contained in:
338
msd2/tracking/piwik/plugins/Live/Visitor.php
Normal file
338
msd2/tracking/piwik/plugins/Live/Visitor.php
Normal file
@ -0,0 +1,338 @@
|
||||
<?php
|
||||
/**
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\Live;
|
||||
|
||||
use Piwik\Cache;
|
||||
use Piwik\CacheId;
|
||||
use Piwik\Config;
|
||||
use Piwik\DataTable\Filter\ColumnDelete;
|
||||
use Piwik\Date;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Plugin;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
|
||||
class Visitor implements VisitorInterface
|
||||
{
|
||||
private $details = array();
|
||||
|
||||
function __construct($visitorRawData)
|
||||
{
|
||||
$this->details = $visitorRawData;
|
||||
}
|
||||
|
||||
function getAllVisitorDetails()
|
||||
{
|
||||
$visitor = array();
|
||||
|
||||
$instances = self::getAllVisitorDetailsInstances();
|
||||
|
||||
foreach ($instances as $instance) {
|
||||
$instance->setDetails($this->details);
|
||||
$instance->extendVisitorDetails($visitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* This event can be used to add any details to a visitor. The visitor's details are for instance used in
|
||||
* API requests like 'Live.getVisitorProfile' and 'Live.getLastVisitDetails'. This can be useful for instance
|
||||
* in case your plugin defines any visit dimensions and you want to add the value of your dimension to a user.
|
||||
* It can be also useful if you want to enrich a visitor with custom fields based on other fields or if you
|
||||
* want to change or remove any fields from the user.
|
||||
*
|
||||
* **Example**
|
||||
*
|
||||
* Piwik::addAction('Live.getAllVisitorDetails', function (&visitor, $details) {
|
||||
* $visitor['userPoints'] = $details['actions'] + $details['events'] + $details['searches'];
|
||||
* unset($visitor['anyFieldYouWantToRemove']);
|
||||
* });
|
||||
*
|
||||
* @param array &visitor You can add or remove fields to the visitor array and it will reflected in the API output
|
||||
* @param array $details The details array contains all visit dimensions (columns of log_visit table)
|
||||
*
|
||||
* @deprecated will be removed in Piwik 4
|
||||
*/
|
||||
Piwik::postEvent('Live.getAllVisitorDetails', array(&$visitor, $this->details));
|
||||
|
||||
return $visitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all available visitor details instances
|
||||
*
|
||||
* @return VisitorDetailsAbstract[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getAllVisitorDetailsInstances()
|
||||
{
|
||||
$cacheId = CacheId::pluginAware('VisitorDetails');
|
||||
$cache = Cache::getTransientCache();
|
||||
|
||||
if (!$cache->contains($cacheId)) {
|
||||
$instances = [
|
||||
new VisitorDetails() // needs to be first
|
||||
];
|
||||
|
||||
/**
|
||||
* Triggered to add new visitor details that cannot be picked up by the platform automatically.
|
||||
*
|
||||
* **Example**
|
||||
*
|
||||
* public function addVisitorDetails(&$visitorDetails)
|
||||
* {
|
||||
* $visitorDetails[] = new CustomVisitorDetails();
|
||||
* }
|
||||
*
|
||||
* @param VisitorDetailsAbstract[] $visitorDetails An array of visitorDetails
|
||||
*/
|
||||
Piwik::postEvent('Live.addVisitorDetails', array(&$instances));
|
||||
|
||||
foreach (self::getAllVisitorDetailsClasses() as $className) {
|
||||
$instance = new $className();
|
||||
|
||||
if ($instance instanceof VisitorDetails) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$instances[] = $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered to filter / restrict vistor details.
|
||||
*
|
||||
* **Example**
|
||||
*
|
||||
* public function filterVisitorDetails(&$visitorDetails)
|
||||
* {
|
||||
* foreach ($visitorDetails as $index => $visitorDetail) {
|
||||
* if (strpos(get_class($visitorDetail), 'MyPluginName') !== false) {}
|
||||
* unset($visitorDetails[$index]); // remove all visitor details for a specific plugin
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @param VisitorDetailsAbstract[] $visitorDetails An array of visitorDetails
|
||||
*/
|
||||
Piwik::postEvent('Live.filterVisitorDetails', array(&$instances));
|
||||
|
||||
$cache->save($cacheId, $instances);
|
||||
}
|
||||
|
||||
return $cache->fetch($cacheId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns class names of all VisitorDetails classes.
|
||||
*
|
||||
* @return string[]
|
||||
* @api
|
||||
*/
|
||||
protected static function getAllVisitorDetailsClasses()
|
||||
{
|
||||
return Plugin\Manager::getInstance()->findComponents('VisitorDetails', 'Piwik\Plugins\Live\VisitorDetailsAbstract');
|
||||
}
|
||||
|
||||
function getVisitorId()
|
||||
{
|
||||
if (isset($this->details['idvisitor'])) {
|
||||
return bin2hex($this->details['idvisitor']);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes fields that are not meant to be displayed (md5 config hash)
|
||||
* Or that the user should only access if they are Super User or admin (cookie, IP)
|
||||
*
|
||||
* @param array $visitorDetails
|
||||
* @return array
|
||||
*/
|
||||
public static function cleanVisitorDetails($visitorDetails)
|
||||
{
|
||||
$toUnset = array('config_id');
|
||||
if (Piwik::isUserIsAnonymous()) {
|
||||
$toUnset[] = 'idvisitor';
|
||||
$toUnset[] = 'user_id';
|
||||
$toUnset[] = 'location_ip';
|
||||
}
|
||||
foreach ($toUnset as $keyName) {
|
||||
if (isset($visitorDetails[$keyName])) {
|
||||
unset($visitorDetails[$keyName]);
|
||||
}
|
||||
}
|
||||
|
||||
return $visitorDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* The &flat=1 feature is used by API.getSuggestedValuesForSegment
|
||||
*
|
||||
* @param $visitorDetailsArray
|
||||
* @return array
|
||||
*/
|
||||
public static function flattenVisitorDetailsArray($visitorDetailsArray)
|
||||
{
|
||||
// NOTE: if you flatten more fields from the "actionDetails" array
|
||||
// ==> also update API/API.php getSuggestedValuesForSegment(), the $segmentsNeedActionsInfo array
|
||||
|
||||
// flatten visit custom variables
|
||||
if (!empty($visitorDetailsArray['customVariables'])
|
||||
&& is_array($visitorDetailsArray['customVariables'])) {
|
||||
foreach ($visitorDetailsArray['customVariables'] as $thisCustomVar) {
|
||||
$visitorDetailsArray = array_merge($visitorDetailsArray, $thisCustomVar);
|
||||
}
|
||||
unset($visitorDetailsArray['customVariables']);
|
||||
}
|
||||
|
||||
// flatten page views custom variables
|
||||
$count = 1;
|
||||
foreach ($visitorDetailsArray['actionDetails'] as $action) {
|
||||
if (!empty($action['customVariables'])) {
|
||||
foreach ($action['customVariables'] as $thisCustomVar) {
|
||||
foreach ($thisCustomVar as $cvKey => $cvValue) {
|
||||
$flattenedKeyName = $cvKey . ColumnDelete::APPEND_TO_COLUMN_NAME_TO_KEEP . $count;
|
||||
$visitorDetailsArray[$flattenedKeyName] = $cvValue;
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flatten Goals
|
||||
$count = 1;
|
||||
foreach ($visitorDetailsArray['actionDetails'] as $action) {
|
||||
if (!empty($action['goalId'])) {
|
||||
$flattenedKeyName = 'visitConvertedGoalId' . ColumnDelete::APPEND_TO_COLUMN_NAME_TO_KEEP . $count;
|
||||
$visitorDetailsArray[$flattenedKeyName] = $action['goalId'];
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Flatten Page Titles/URLs
|
||||
$count = 1;
|
||||
foreach ($visitorDetailsArray['actionDetails'] as $action) {
|
||||
|
||||
// API.getSuggestedValuesForSegment
|
||||
$flattenForActionType = array(
|
||||
'outlink' => 'outlinkUrl',
|
||||
'download' => 'downloadUrl',
|
||||
'event' => 'eventUrl',
|
||||
'action' => 'pageUrl'
|
||||
);
|
||||
foreach($flattenForActionType as $actionType => $flattenedKeyPrefix) {
|
||||
if (!empty($action['url'])
|
||||
&& $action['type'] == $actionType) {
|
||||
$flattenedKeyName = $flattenedKeyPrefix . ColumnDelete::APPEND_TO_COLUMN_NAME_TO_KEEP . $count;
|
||||
$visitorDetailsArray[$flattenedKeyName] = $action['url'];
|
||||
}
|
||||
}
|
||||
|
||||
$flatten = array( 'pageTitle', 'siteSearchKeyword', 'eventCategory', 'eventAction', 'eventName', 'eventValue');
|
||||
foreach($flatten as $toFlatten) {
|
||||
if (!empty($action[$toFlatten])) {
|
||||
$flattenedKeyName = $toFlatten . ColumnDelete::APPEND_TO_COLUMN_NAME_TO_KEEP . $count;
|
||||
$visitorDetailsArray[$flattenedKeyName] = $action[$toFlatten];
|
||||
}
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
|
||||
// Entry/exit pages
|
||||
$firstAction = $lastAction = false;
|
||||
foreach ($visitorDetailsArray['actionDetails'] as $action) {
|
||||
if ($action['type'] == 'action') {
|
||||
if (empty($firstAction)) {
|
||||
$firstAction = $action;
|
||||
}
|
||||
$lastAction = $action;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($firstAction['pageTitle'])) {
|
||||
$visitorDetailsArray['entryPageTitle'] = $firstAction['pageTitle'];
|
||||
}
|
||||
if (!empty($firstAction['url'])) {
|
||||
$visitorDetailsArray['entryPageUrl'] = $firstAction['url'];
|
||||
}
|
||||
if (!empty($lastAction['pageTitle'])) {
|
||||
$visitorDetailsArray['exitPageTitle'] = $lastAction['pageTitle'];
|
||||
}
|
||||
if (!empty($lastAction['url'])) {
|
||||
$visitorDetailsArray['exitPageUrl'] = $lastAction['url'];
|
||||
}
|
||||
|
||||
return $visitorDetailsArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $visitorDetailsArray
|
||||
* @param array $actionDetails preset action details
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function enrichVisitorArrayWithActions($visitorDetailsArray, $actionDetails = array())
|
||||
{
|
||||
$actionsLimit = (int)Config::getInstance()->General['visitor_log_maximum_actions_per_visit'];
|
||||
$visitorDetailsManipulators = self::getAllVisitorDetailsInstances();
|
||||
|
||||
foreach ($visitorDetailsManipulators as $instance) {
|
||||
$instance->provideActionsForVisit($actionDetails, $visitorDetailsArray);
|
||||
}
|
||||
|
||||
foreach ($visitorDetailsManipulators as $instance) {
|
||||
$instance->filterActions($actionDetails, $visitorDetailsArray);
|
||||
}
|
||||
|
||||
usort($actionDetails, array('static', 'sortByServerTime'));
|
||||
|
||||
$actionDetails = array_values($actionDetails);
|
||||
|
||||
// limit actions
|
||||
if ($actionsLimit < count($actionDetails)) {
|
||||
$visitorDetailsArray['truncatedActionsCount'] = count($actionDetails) - $actionsLimit;
|
||||
$actionDetails = array_slice($actionDetails, 0, $actionsLimit);
|
||||
}
|
||||
|
||||
foreach ($actionDetails as $actionIdx => &$actionDetail) {
|
||||
$actionDetail =& $actionDetails[$actionIdx];
|
||||
$nextAction = isset($actionDetails[$actionIdx+1]) ? $actionDetails[$actionIdx+1] : null;
|
||||
|
||||
foreach ($visitorDetailsManipulators as $instance) {
|
||||
$instance->extendActionDetails($actionDetail, $nextAction, $visitorDetailsArray);
|
||||
}
|
||||
}
|
||||
|
||||
$visitorDetailsArray['actionDetails'] = $actionDetails;
|
||||
|
||||
return $visitorDetailsArray;
|
||||
}
|
||||
|
||||
private static function sortByServerTime($a, $b)
|
||||
{
|
||||
$ta = strtotime($a['serverTimePretty']);
|
||||
$tb = strtotime($b['serverTimePretty']);
|
||||
|
||||
if ($ta < $tb) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ($ta == $tb) {
|
||||
if ($a['idlink_va'] == $b['idlink_va']) {
|
||||
return strcmp($a['type'], $b['type']);
|
||||
}
|
||||
|
||||
if ($a['idlink_va'] > $b['idlink_va']) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user