PDF rausgenommen
This commit is contained in:
275
msd2/tracking/piwik/plugins/CustomVariables/Archiver.php
Normal file
275
msd2/tracking/piwik/plugins/CustomVariables/Archiver.php
Normal file
@ -0,0 +1,275 @@
|
||||
<?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\CustomVariables;
|
||||
|
||||
use Piwik\Config;
|
||||
use Piwik\DataAccess\LogAggregator;
|
||||
use Piwik\DataArray;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
use Piwik\Tracker;
|
||||
|
||||
require_once PIWIK_INCLUDE_PATH . '/libs/PiwikTracker/PiwikTracker.php';
|
||||
|
||||
class Archiver extends \Piwik\Plugin\Archiver
|
||||
{
|
||||
const LABEL_CUSTOM_VALUE_NOT_DEFINED = "Value not defined";
|
||||
const CUSTOM_VARIABLE_RECORD_NAME = 'CustomVariables_valueByName';
|
||||
|
||||
// Ecommerce reports use custom variables.
|
||||
// We specifically set the limits high to get accurate Ecommerce reports
|
||||
const MAX_ROWS_WHEN_ECOMMERCE = 50000;
|
||||
|
||||
/**
|
||||
* @var DataArray
|
||||
*/
|
||||
protected $dataArray;
|
||||
protected $maximumRowsInDataTableLevelZero;
|
||||
protected $maximumRowsInSubDataTable;
|
||||
protected $newEmptyRow;
|
||||
|
||||
private $metadata = array();
|
||||
private $metadataFlat = array();
|
||||
|
||||
function __construct($processor)
|
||||
{
|
||||
parent::__construct($processor);
|
||||
|
||||
if ($processor->getParams()->getSite()->isEcommerceEnabled()) {
|
||||
$this->maximumRowsInDataTableLevelZero = self::MAX_ROWS_WHEN_ECOMMERCE;
|
||||
$this->maximumRowsInSubDataTable = self::MAX_ROWS_WHEN_ECOMMERCE;
|
||||
} else {
|
||||
$this->maximumRowsInDataTableLevelZero = Config::getInstance()->General['datatable_archiving_maximum_rows_custom_variables'];
|
||||
$this->maximumRowsInSubDataTable = Config::getInstance()->General['datatable_archiving_maximum_rows_subtable_custom_variables'];
|
||||
}
|
||||
}
|
||||
|
||||
public function aggregateMultipleReports()
|
||||
{
|
||||
$columnsAggregationOperation = array('slots' => 'uniquearraymerge');
|
||||
|
||||
$this->getProcessor()->aggregateDataTableRecords(
|
||||
self::CUSTOM_VARIABLE_RECORD_NAME,
|
||||
$this->maximumRowsInDataTableLevelZero,
|
||||
$this->maximumRowsInSubDataTable,
|
||||
$columnToSort = Metrics::INDEX_NB_VISITS,
|
||||
$columnsAggregationOperation,
|
||||
$columnsToRenameAfterAggregation = null,
|
||||
$countRowsRecursive = array());
|
||||
}
|
||||
|
||||
public function aggregateDayReport()
|
||||
{
|
||||
$this->dataArray = new DataArray();
|
||||
|
||||
$maxCustomVariables = CustomVariables::getNumUsableCustomVariables();
|
||||
for ($i = 1; $i <= $maxCustomVariables; $i++) {
|
||||
$this->aggregateCustomVariable($i);
|
||||
}
|
||||
|
||||
$this->removeVisitsMetricsFromActionsAggregate();
|
||||
$this->dataArray->enrichMetricsWithConversions();
|
||||
$table = $this->dataArray->asDataTable();
|
||||
|
||||
foreach ($table->getRows() as $row) {
|
||||
$label = $row->getColumn('label');
|
||||
if (!empty($this->metadata[$label])) {
|
||||
foreach ($this->metadata[$label] as $name => $value) {
|
||||
$row->addMetadata($name, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$blob = $table->getSerialized(
|
||||
$this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable,
|
||||
$columnToSort = Metrics::INDEX_NB_VISITS
|
||||
);
|
||||
|
||||
$this->getProcessor()->insertBlobRecord(self::CUSTOM_VARIABLE_RECORD_NAME, $blob);
|
||||
}
|
||||
|
||||
protected function aggregateCustomVariable($slot)
|
||||
{
|
||||
$keyField = "custom_var_k" . $slot;
|
||||
$valueField = "custom_var_v" . $slot;
|
||||
$where = "%s.$keyField != ''";
|
||||
$dimensions = array($keyField, $valueField);
|
||||
|
||||
$query = $this->getLogAggregator()->queryVisitsByDimension($dimensions, $where);
|
||||
$this->aggregateFromVisits($query, $keyField, $valueField);
|
||||
|
||||
// IF we query Custom Variables scope "page" either: Product SKU, Product Name,
|
||||
// then we also query the "Product page view" price which was possibly recorded.
|
||||
$additionalSelects = false;
|
||||
|
||||
if (in_array($slot, array(\PiwikTracker::CVAR_INDEX_ECOMMERCE_ITEM_SKU, \PiwikTracker::CVAR_INDEX_ECOMMERCE_ITEM_NAME, \PiwikTracker::CVAR_INDEX_ECOMMERCE_ITEM_CATEGORY))) {
|
||||
$additionalSelects = array($this->getSelectAveragePrice());
|
||||
}
|
||||
$query = $this->getLogAggregator()->queryActionsByDimension($dimensions, $where, $additionalSelects);
|
||||
$this->aggregateFromActions($query, $keyField, $valueField);
|
||||
|
||||
$query = $this->getLogAggregator()->queryConversionsByDimension($dimensions, $where);
|
||||
$this->aggregateFromConversions($query, $keyField, $valueField);
|
||||
}
|
||||
|
||||
protected function getSelectAveragePrice()
|
||||
{
|
||||
$field = "custom_var_v" . \PiwikTracker::CVAR_INDEX_ECOMMERCE_ITEM_PRICE;
|
||||
return LogAggregator::getSqlRevenue("AVG(log_link_visit_action." . $field . ")") . " as `" . Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED . "`";
|
||||
}
|
||||
|
||||
protected function aggregateFromVisits($query, $keyField, $valueField)
|
||||
{
|
||||
while ($row = $query->fetch()) {
|
||||
$key = $row[$keyField];
|
||||
$value = $this->cleanCustomVarValue($row[$valueField]);
|
||||
|
||||
$this->addMetadata($keyField, $key, Model::SCOPE_VISIT);
|
||||
|
||||
$this->dataArray->sumMetricsVisits($key, $row);
|
||||
$this->dataArray->sumMetricsVisitsPivot($key, $value, $row);
|
||||
}
|
||||
}
|
||||
|
||||
protected function cleanCustomVarValue($value)
|
||||
{
|
||||
if (strlen($value)) {
|
||||
return $value;
|
||||
}
|
||||
return self::LABEL_CUSTOM_VALUE_NOT_DEFINED;
|
||||
}
|
||||
|
||||
protected function aggregateFromActions($query, $keyField, $valueField)
|
||||
{
|
||||
while ($row = $query->fetch()) {
|
||||
$key = $row[$keyField];
|
||||
$value = $this->cleanCustomVarValue($row[$valueField]);
|
||||
|
||||
$this->addMetadata($keyField, $key, Model::SCOPE_PAGE);
|
||||
|
||||
$alreadyAggregated = $this->aggregateEcommerceCategories($key, $value, $row);
|
||||
if (!$alreadyAggregated) {
|
||||
$this->aggregateActionByKeyAndValue($key, $value, $row);
|
||||
$this->dataArray->sumMetricsActions($key, $row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addMetadata($keyField, $label, $scope)
|
||||
{
|
||||
$index = (int) str_replace('custom_var_k', '', $keyField);
|
||||
|
||||
if (!array_key_exists($label, $this->metadata)) {
|
||||
$this->metadata[$label] = array('slots' => array());
|
||||
}
|
||||
|
||||
$uniqueId = $label . 'scope' . $scope . 'index' . $index;
|
||||
|
||||
if (!isset($this->metadataFlat[$uniqueId])) {
|
||||
$this->metadata[$label]['slots'][] = array('scope' => $scope, 'index' => $index);
|
||||
$this->metadataFlat[$uniqueId] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @param $row
|
||||
* @return bool True if the $row metrics were already added to the ->metrics
|
||||
*/
|
||||
protected function aggregateEcommerceCategories($key, $value, $row)
|
||||
{
|
||||
$ecommerceCategoriesAggregated = false;
|
||||
if ($key == '_pkc'
|
||||
&& $value[0] == '[' && $value[1] == '"'
|
||||
) {
|
||||
// In case categories were truncated, try closing the array
|
||||
if (substr($value, -2) != '"]') {
|
||||
$value .= '"]';
|
||||
}
|
||||
$decoded = json_decode($value);
|
||||
if (is_array($decoded)) {
|
||||
$count = 0;
|
||||
foreach ($decoded as $category) {
|
||||
if (empty($category)
|
||||
|| $count >= GoalManager::MAXIMUM_PRODUCT_CATEGORIES
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
$this->aggregateActionByKeyAndValue($key, $category, $row);
|
||||
$ecommerceCategoriesAggregated = true;
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ecommerceCategoriesAggregated;
|
||||
}
|
||||
|
||||
protected function aggregateActionByKeyAndValue($key, $value, $row)
|
||||
{
|
||||
$this->dataArray->sumMetricsActionsPivot($key, $value, $row);
|
||||
|
||||
if ($this->isReservedKey($key)) {
|
||||
// Price tracking on Ecommerce product/category pages:
|
||||
// the average is returned from the SQL query so the price is not "summed" like other metrics
|
||||
$index = Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED;
|
||||
if (!empty($row[$index])) {
|
||||
$this->dataArray->setRowColumnPivot($key, $value, $index, (float)$row[$index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static function isReservedKey($key)
|
||||
{
|
||||
return in_array($key, API::getReservedCustomVariableKeys());
|
||||
}
|
||||
|
||||
protected function aggregateFromConversions($query, $keyField, $valueField)
|
||||
{
|
||||
if ($query === false) {
|
||||
return;
|
||||
}
|
||||
while ($row = $query->fetch()) {
|
||||
$key = $row[$keyField];
|
||||
|
||||
$value = $this->cleanCustomVarValue($row[$valueField]);
|
||||
$this->dataArray->sumMetricsGoals($key, $row);
|
||||
$this->dataArray->sumMetricsGoalsPivot($key, $value, $row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Visit, Unique Visitor and Users metric from 'page' scope custom variables.
|
||||
*
|
||||
* - Custom variables of 'visit' scope: it is expected that these ones have the "visit" column set.
|
||||
* - Custom variables of 'page' scope: we cannot process "Visits" count for these.
|
||||
* Why?
|
||||
* "Actions" column is processed with a SELECT count(*).
|
||||
* A same visit can set the same custom variable of 'page' scope multiple times.
|
||||
* We cannot sum the values of count(*) as it would be incorrect.
|
||||
* The way we could process "Visits" Metric for 'page' scope variable is to issue a count(Distinct *) or so,
|
||||
* but it is no implemented yet (this would likely be very slow for high traffic sites).
|
||||
*
|
||||
*/
|
||||
protected function removeVisitsMetricsFromActionsAggregate()
|
||||
{
|
||||
$dataArray = & $this->dataArray->getDataArray();
|
||||
foreach ($dataArray as $key => &$row) {
|
||||
if (!self::isReservedKey($key)
|
||||
&& DataArray::isRowActions($row)
|
||||
) {
|
||||
unset($row[Metrics::INDEX_NB_UNIQ_VISITORS]);
|
||||
unset($row[Metrics::INDEX_NB_VISITS]);
|
||||
unset($row[Metrics::INDEX_NB_USERS]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user