update Piwik to version 2.16 (fixes #91)
This commit is contained in:
parent
9abe039dc8
commit
47263617c5
93 changed files with 418860 additions and 226988 deletions
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -9,15 +9,24 @@
|
|||
namespace Piwik\Plugins\Goals;
|
||||
|
||||
use Exception;
|
||||
use Piwik\API\Request;
|
||||
use Piwik\Archive;
|
||||
use Piwik\CacheId;
|
||||
use Piwik\Cache as PiwikCache;
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Db;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\Report;
|
||||
use Piwik\Plugins\API\DataTable\MergeDataTables;
|
||||
use Piwik\Plugins\CoreHome\Columns\Metrics\ConversionRate;
|
||||
use Piwik\Plugins\Goals\Columns\Metrics\AverageOrderRevenue;
|
||||
use Piwik\Segment\SegmentExpression;
|
||||
use Piwik\Site;
|
||||
use Piwik\Tracker\Cache;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
use Piwik\Plugins\VisitFrequency\API as VisitFrequencyAPI;
|
||||
|
||||
/**
|
||||
* Goals API lets you Manage existing goals, via "updateGoal" and "deleteGoal", create new Goals via "addGoal",
|
||||
|
|
@ -35,7 +44,7 @@ use Piwik\Tracker\GoalManager;
|
|||
* If you wish to request specific metrics about Ecommerce goals, you can set the parameter &idGoal=ecommerceAbandonedCart to get metrics about abandoned carts (including Lost revenue, and number of items left in the cart)
|
||||
* or &idGoal=ecommerceOrder to get metrics about Ecommerce orders (number of orders, visits with an order, subtotal, tax, shipping, discount, revenue, items ordered)
|
||||
*
|
||||
* See also the documentation about <a href='http://piwik.org/docs/tracking-goals-web-analytics/' target='_blank'>Tracking Goals</a> in Piwik.
|
||||
* See also the documentation about <a href='http://piwik.org/docs/tracking-goals-web-analytics/' rel='noreferrer' target='_blank'>Tracking Goals</a> in Piwik.
|
||||
*
|
||||
* @method static \Piwik\Plugins\Goals\API getInstance()
|
||||
*/
|
||||
|
|
@ -51,27 +60,33 @@ class API extends \Piwik\Plugin\API
|
|||
*/
|
||||
public function getGoals($idSite)
|
||||
{
|
||||
//TODO calls to this function could be cached as static
|
||||
// would help UI at least, since some UI requests would call this 2-3 times..
|
||||
$idSite = Site::getIdSitesFromIdSitesString($idSite);
|
||||
if (empty($idSite)) {
|
||||
return array();
|
||||
}
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
$goals = Db::fetchAll("SELECT *
|
||||
FROM " . Common::prefixTable('goal') . "
|
||||
WHERE idsite IN (" . implode(", ", $idSite) . ")
|
||||
AND deleted = 0");
|
||||
$cleanedGoals = array();
|
||||
foreach ($goals as &$goal) {
|
||||
if ($goal['match_attribute'] == 'manually') {
|
||||
unset($goal['pattern']);
|
||||
unset($goal['pattern_type']);
|
||||
unset($goal['case_sensitive']);
|
||||
$cacheId = self::getCacheId($idSite);
|
||||
$cache = $this->getGoalsInfoStaticCache();
|
||||
if (!$cache->contains($cacheId)) {
|
||||
$idSite = Site::getIdSitesFromIdSitesString($idSite);
|
||||
|
||||
if (empty($idSite)) {
|
||||
return array();
|
||||
}
|
||||
$cleanedGoals[$goal['idgoal']] = $goal;
|
||||
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
|
||||
$goals = $this->getModel()->getActiveGoals($idSite);
|
||||
|
||||
$cleanedGoals = array();
|
||||
foreach ($goals as &$goal) {
|
||||
if ($goal['match_attribute'] == 'manually') {
|
||||
unset($goal['pattern']);
|
||||
unset($goal['pattern_type']);
|
||||
unset($goal['case_sensitive']);
|
||||
}
|
||||
$cleanedGoals[$goal['idgoal']] = $goal;
|
||||
}
|
||||
|
||||
$cache->save($cacheId, $cleanedGoals);
|
||||
}
|
||||
return $cleanedGoals;
|
||||
|
||||
return $cache->fetch($cacheId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -79,7 +94,7 @@ class API extends \Piwik\Plugin\API
|
|||
*
|
||||
* @param int $idSite
|
||||
* @param string $name
|
||||
* @param string $matchAttribute 'url', 'title', 'file', 'external_website' or 'manually'
|
||||
* @param string $matchAttribute 'url', 'title', 'file', 'external_website', 'manually', 'event_action', 'event_category' or 'event_name'
|
||||
* @param string $pattern eg. purchase-confirmation.htm
|
||||
* @param string $patternType 'regex', 'contains', 'exact'
|
||||
* @param bool $caseSensitive
|
||||
|
|
@ -91,35 +106,37 @@ class API extends \Piwik\Plugin\API
|
|||
public function addGoal($idSite, $name, $matchAttribute, $pattern, $patternType, $caseSensitive = false, $revenue = false, $allowMultipleConversionsPerVisit = false)
|
||||
{
|
||||
Piwik::checkUserHasAdminAccess($idSite);
|
||||
$this->checkPatternIsValid($patternType, $pattern);
|
||||
$name = $this->checkName($name);
|
||||
|
||||
$this->checkPatternIsValid($patternType, $pattern, $matchAttribute);
|
||||
$name = $this->checkName($name);
|
||||
$pattern = $this->checkPattern($pattern);
|
||||
|
||||
// save in db
|
||||
$db = Db::get();
|
||||
$idGoal = $db->fetchOne("SELECT max(idgoal) + 1
|
||||
FROM " . Common::prefixTable('goal') . "
|
||||
WHERE idsite = ?", $idSite);
|
||||
if ($idGoal == false) {
|
||||
$idGoal = 1;
|
||||
}
|
||||
$db->insert(Common::prefixTable('goal'),
|
||||
array(
|
||||
'idsite' => $idSite,
|
||||
'idgoal' => $idGoal,
|
||||
'name' => $name,
|
||||
'match_attribute' => $matchAttribute,
|
||||
'pattern' => $pattern,
|
||||
'pattern_type' => $patternType,
|
||||
'case_sensitive' => (int)$caseSensitive,
|
||||
'allow_multiple' => (int)$allowMultipleConversionsPerVisit,
|
||||
'revenue' => (float)$revenue,
|
||||
'deleted' => 0,
|
||||
));
|
||||
$revenue = Common::forceDotAsSeparatorForDecimalPoint((float)$revenue);
|
||||
|
||||
$goal = array(
|
||||
'name' => $name,
|
||||
'match_attribute' => $matchAttribute,
|
||||
'pattern' => $pattern,
|
||||
'pattern_type' => $patternType,
|
||||
'case_sensitive' => (int)$caseSensitive,
|
||||
'allow_multiple' => (int)$allowMultipleConversionsPerVisit,
|
||||
'revenue' => $revenue,
|
||||
'deleted' => 0,
|
||||
);
|
||||
|
||||
$idGoal = $this->getModel()->createGoalForSite($idSite, $goal);
|
||||
|
||||
$this->getGoalsInfoStaticCache()->delete(self::getCacheId($idSite));
|
||||
|
||||
Cache::regenerateCacheWebsiteAttributes($idSite);
|
||||
return $idGoal;
|
||||
}
|
||||
|
||||
private function getModel()
|
||||
{
|
||||
return new Model();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a Goal description.
|
||||
* Will not update or re-process the conversions already recorded
|
||||
|
|
@ -139,28 +156,33 @@ class API extends \Piwik\Plugin\API
|
|||
public function updateGoal($idSite, $idGoal, $name, $matchAttribute, $pattern, $patternType, $caseSensitive = false, $revenue = false, $allowMultipleConversionsPerVisit = false)
|
||||
{
|
||||
Piwik::checkUserHasAdminAccess($idSite);
|
||||
$name = $this->checkName($name);
|
||||
|
||||
$name = $this->checkName($name);
|
||||
$pattern = $this->checkPattern($pattern);
|
||||
$this->checkPatternIsValid($patternType, $pattern);
|
||||
Db::get()->update(Common::prefixTable('goal'),
|
||||
array(
|
||||
'name' => $name,
|
||||
'match_attribute' => $matchAttribute,
|
||||
'pattern' => $pattern,
|
||||
'pattern_type' => $patternType,
|
||||
'case_sensitive' => (int)$caseSensitive,
|
||||
'allow_multiple' => (int)$allowMultipleConversionsPerVisit,
|
||||
'revenue' => (float)$revenue,
|
||||
),
|
||||
"idsite = '$idSite' AND idgoal = '$idGoal'"
|
||||
);
|
||||
$this->checkPatternIsValid($patternType, $pattern, $matchAttribute);
|
||||
|
||||
$revenue = Common::forceDotAsSeparatorForDecimalPoint((float)$revenue);
|
||||
|
||||
$this->getModel()->updateGoal($idSite, $idGoal, array(
|
||||
'name' => $name,
|
||||
'match_attribute' => $matchAttribute,
|
||||
'pattern' => $pattern,
|
||||
'pattern_type' => $patternType,
|
||||
'case_sensitive' => (int) $caseSensitive,
|
||||
'allow_multiple' => (int) $allowMultipleConversionsPerVisit,
|
||||
'revenue' => $revenue,
|
||||
));
|
||||
|
||||
$this->getGoalsInfoStaticCache()->delete(self::getCacheId($idSite));
|
||||
|
||||
Cache::regenerateCacheWebsiteAttributes($idSite);
|
||||
}
|
||||
|
||||
private function checkPatternIsValid($patternType, $pattern)
|
||||
private function checkPatternIsValid($patternType, $pattern, $matchAttribute)
|
||||
{
|
||||
if ($patternType == 'exact'
|
||||
&& substr($pattern, 0, 4) != 'http'
|
||||
&& substr($matchAttribute, 0, 6) != 'event_'
|
||||
) {
|
||||
throw new Exception(Piwik::translate('Goals_ExceptionInvalidMatchingString', array("http:// or https://", "http://www.yourwebsite.com/newsletter/subscribed.html")));
|
||||
}
|
||||
|
|
@ -187,12 +209,12 @@ class API extends \Piwik\Plugin\API
|
|||
public function deleteGoal($idSite, $idGoal)
|
||||
{
|
||||
Piwik::checkUserHasAdminAccess($idSite);
|
||||
Db::query("UPDATE " . Common::prefixTable('goal') . "
|
||||
SET deleted = 1
|
||||
WHERE idsite = ?
|
||||
AND idgoal = ?",
|
||||
array($idSite, $idGoal));
|
||||
Db::deleteAllRows(Common::prefixTable("log_conversion"), "WHERE idgoal = ? AND idsite = ?", "idvisit", 100000, array($idGoal, $idSite));
|
||||
|
||||
$this->getModel()->deleteGoal($idSite, $idGoal);
|
||||
$this->getModel()->deleteGoalConversions($idSite, $idGoal);
|
||||
|
||||
$this->getGoalsInfoStaticCache()->delete(self::getCacheId($idSite));
|
||||
|
||||
Cache::regenerateCacheWebsiteAttributes($idSite);
|
||||
}
|
||||
|
||||
|
|
@ -203,41 +225,31 @@ class API extends \Piwik\Plugin\API
|
|||
protected function getItems($recordName, $idSite, $period, $date, $abandonedCarts, $segment)
|
||||
{
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
|
||||
$recordNameFinal = $recordName;
|
||||
if ($abandonedCarts) {
|
||||
$recordNameFinal = Archiver::getItemRecordNameAbandonedCart($recordName);
|
||||
}
|
||||
$archive = Archive::build($idSite, $period, $date, $segment);
|
||||
$dataTable = $archive->getDataTable($recordNameFinal);
|
||||
|
||||
$dataTable->filter('Sort', array(Metrics::INDEX_ECOMMERCE_ITEM_REVENUE));
|
||||
$archive = Archive::build($idSite, $period, $date, $segment);
|
||||
$dataTable = $archive->getDataTable($recordNameFinal);
|
||||
|
||||
$this->enrichItemsTableWithViewMetrics($dataTable, $recordName, $idSite, $period, $date, $segment);
|
||||
|
||||
// First rename the avg_price_viewed column
|
||||
$renameColumn = array(self::AVG_PRICE_VIEWED => 'avg_price');
|
||||
$dataTable->queueFilter('ReplaceColumnNames', array($renameColumn));
|
||||
$dataTable->filter('ReplaceColumnNames', array($renameColumn));
|
||||
|
||||
$dataTable->queueFilter('ReplaceColumnNames');
|
||||
$dataTable->queueFilter('ReplaceSummaryRowLabel');
|
||||
|
||||
$ordersColumn = 'orders';
|
||||
if ($abandonedCarts) {
|
||||
$ordersColumn = 'abandoned_carts';
|
||||
$dataTable->renameColumn(Metrics::INDEX_ECOMMERCE_ORDERS, $ordersColumn);
|
||||
}
|
||||
|
||||
// Average price = sum product revenue / quantity
|
||||
$dataTable->queueFilter('ColumnCallbackAddColumnQuotient', array('avg_price', 'price', $ordersColumn, GoalManager::REVENUE_PRECISION));
|
||||
|
||||
// Average quantity = sum product quantity / abandoned carts
|
||||
$dataTable->queueFilter('ColumnCallbackAddColumnQuotient',
|
||||
array('avg_quantity', 'quantity', $ordersColumn, $precision = 1));
|
||||
$dataTable->queueFilter('ColumnDelete', array('price'));
|
||||
|
||||
// Product conversion rate = orders / visits
|
||||
$dataTable->queueFilter('ColumnCallbackAddColumnPercentage', array('conversion_rate', $ordersColumn, 'nb_visits', GoalManager::REVENUE_PRECISION));
|
||||
|
||||
return $dataTable;
|
||||
}
|
||||
|
||||
|
|
@ -249,6 +261,7 @@ class API extends \Piwik\Plugin\API
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$rowNotDefined = $dataTable->getRowFromLabel(\Piwik\Plugins\CustomVariables\Archiver::LABEL_CUSTOM_VALUE_NOT_DEFINED);
|
||||
if ($rowNotDefined) {
|
||||
$rowNotDefined->setColumn('label', $notDefinedStringPretty);
|
||||
|
|
@ -318,7 +331,7 @@ class API extends \Piwik\Plugin\API
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns Goals data
|
||||
* Returns Goals data.
|
||||
*
|
||||
* @param int $idSite
|
||||
* @param string $period
|
||||
|
|
@ -329,62 +342,134 @@ class API extends \Piwik\Plugin\API
|
|||
* @return DataTable
|
||||
*/
|
||||
public function get($idSite, $period, $date, $segment = false, $idGoal = false, $columns = array())
|
||||
{
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
|
||||
/** @var DataTable|DataTable\Map $table */
|
||||
$table = null;
|
||||
|
||||
$segments = array(
|
||||
'' => false,
|
||||
'_new_visit' => 'visitorType%3D%3Dnew', // visitorType==new
|
||||
'_returning_visit' => VisitFrequencyAPI::RETURNING_VISITOR_SEGMENT
|
||||
);
|
||||
|
||||
foreach ($segments as $appendToMetricName => $predefinedSegment) {
|
||||
$segmentToUse = $this->appendSegment($predefinedSegment, $segment);
|
||||
|
||||
/** @var DataTable|DataTable\Map $tableSegmented */
|
||||
$tableSegmented = Request::processRequest('Goals.getMetrics', array(
|
||||
'segment' => $segmentToUse,
|
||||
'idSite' => $idSite,
|
||||
'period' => $period,
|
||||
'date' => $date,
|
||||
'idGoal' => $idGoal,
|
||||
'columns' => $columns,
|
||||
'format_metrics' => 'bc'
|
||||
));
|
||||
|
||||
$tableSegmented->filter('Piwik\Plugins\Goals\DataTable\Filter\AppendNameToColumnNames',
|
||||
array($appendToMetricName));
|
||||
|
||||
if (!isset($table)) {
|
||||
$table = $tableSegmented;
|
||||
} else {
|
||||
$merger = new MergeDataTables();
|
||||
$merger->mergeDataTables($table, $tableSegmented);
|
||||
}
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link get()} but does not return any metrics for new and returning visitors. It won't apply
|
||||
* any segment by default. This method is deprecated from the API as it is only there to make the implementation of
|
||||
* the actual {@link get()} method easy.
|
||||
*
|
||||
* @deprecated
|
||||
* @internal
|
||||
*/
|
||||
public function getMetrics($idSite, $period, $date, $segment = false, $idGoal = false, $columns = array())
|
||||
{
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
$archive = Archive::build($idSite, $period, $date, $segment);
|
||||
$columns = Piwik::getArrayFromApiParameter($columns);
|
||||
|
||||
// Mapping string idGoal to internal ID
|
||||
$idGoal = self::convertSpecialGoalIds($idGoal);
|
||||
$isEcommerceGoal = $idGoal === GoalManager::IDGOAL_ORDER || $idGoal === GoalManager::IDGOAL_CART;
|
||||
|
||||
if (empty($columns)) {
|
||||
$columns = Goals::getGoalColumns($idGoal);
|
||||
if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
|
||||
$columns[] = 'avg_order_revenue';
|
||||
}
|
||||
}
|
||||
if (in_array('avg_order_revenue', $columns)
|
||||
&& $idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER
|
||||
) {
|
||||
$columns[] = 'nb_conversions';
|
||||
$columns[] = 'revenue';
|
||||
$columns = array_values(array_unique($columns));
|
||||
}
|
||||
$columnsToSelect = array();
|
||||
foreach ($columns as &$columnName) {
|
||||
$columnsToSelect[] = Archiver::getRecordName($columnName, $idGoal);
|
||||
}
|
||||
$dataTable = $archive->getDataTableFromNumeric($columnsToSelect);
|
||||
$allMetrics = Goals::getGoalColumns($idGoal);
|
||||
$columnsToShow = Piwik::getArrayFromApiParameter($columns);
|
||||
$requestedColumns = $columnsToShow;
|
||||
|
||||
// Rewrite column names as we expect them
|
||||
foreach ($columnsToSelect as $id => $oldName) {
|
||||
$dataTable->renameColumn($oldName, $columns[$id]);
|
||||
$shouldAddAverageOrderRevenue = (in_array('avg_order_revenue', $requestedColumns) || empty($requestedColumns)) && $isEcommerceGoal;
|
||||
|
||||
if ($shouldAddAverageOrderRevenue && !empty($requestedColumns)) {
|
||||
|
||||
$avgOrder = new AverageOrderRevenue();
|
||||
$metricsToAdd = $avgOrder->getDependentMetrics();
|
||||
|
||||
$requestedColumns = array_unique(array_merge($requestedColumns, $metricsToAdd));
|
||||
}
|
||||
if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
|
||||
if ($dataTable instanceof DataTable\Map) {
|
||||
foreach ($dataTable->getDataTables() as $row) {
|
||||
$this->enrichTable($row);
|
||||
|
||||
$report = Report::factory('Goals', 'getMetrics');
|
||||
$columnsToGet = $report->getMetricsRequiredForReport($allMetrics, $requestedColumns);
|
||||
|
||||
$inDbMetricNames = array_map(function ($name) use ($idGoal) {
|
||||
return $name == 'nb_visits' ? $name : Archiver::getRecordName($name, $idGoal);
|
||||
}, $columnsToGet);
|
||||
$dataTable = $archive->getDataTableFromNumeric($inDbMetricNames);
|
||||
|
||||
if (count($columnsToGet) > 0) {
|
||||
$newNameMapping = array_combine($inDbMetricNames, $columnsToGet);
|
||||
} else {
|
||||
$newNameMapping = array();
|
||||
}
|
||||
$dataTable->filter('ReplaceColumnNames', array($newNameMapping));
|
||||
|
||||
// TODO: this should be in Goals/Get.php but it depends on idGoal parameter which isn't always in _GET (ie,
|
||||
// it's not in ProcessedReport.php). more refactoring must be done to report class before this can be
|
||||
// corrected.
|
||||
if ($shouldAddAverageOrderRevenue) {
|
||||
$dataTable->filter(function (DataTable $table) {
|
||||
$extraProcessedMetrics = $table->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME);
|
||||
if (empty($extraProcessedMetrics)) {
|
||||
$extraProcessedMetrics = array();
|
||||
}
|
||||
} else {
|
||||
$this->enrichTable($dataTable);
|
||||
$extraProcessedMetrics[] = new AverageOrderRevenue();
|
||||
$table->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, $extraProcessedMetrics);
|
||||
});
|
||||
}
|
||||
|
||||
// remove temporary metrics that were not explicitly requested
|
||||
if (empty($columnsToShow)) {
|
||||
$columnsToShow = $allMetrics;
|
||||
$columnsToShow[] = 'conversion_rate';
|
||||
if ($isEcommerceGoal) {
|
||||
$columnsToShow[] = 'avg_order_revenue';
|
||||
}
|
||||
}
|
||||
|
||||
$dataTable->queueFilter('ColumnDelete', array($columnsToRemove = array(), $columnsToShow));
|
||||
|
||||
return $dataTable;
|
||||
}
|
||||
|
||||
protected function enrichTable($table)
|
||||
protected function appendSegment($segment, $segmentToAppend)
|
||||
{
|
||||
$row = $table->getFirstRow();
|
||||
if (!$row) {
|
||||
return;
|
||||
if (empty($segment)) {
|
||||
return $segmentToAppend;
|
||||
}
|
||||
// AVG order per visit
|
||||
if (false !== $table->getColumn('avg_order_revenue')) {
|
||||
$conversions = $row->getColumn('nb_conversions');
|
||||
if ($conversions) {
|
||||
$row->setColumn('avg_order_revenue', round($row->getColumn('revenue') / $conversions, 2));
|
||||
}
|
||||
|
||||
if (empty($segmentToAppend)) {
|
||||
return $segment;
|
||||
}
|
||||
|
||||
$segment .= urlencode(SegmentExpression::AND_DELIMITER);
|
||||
$segment .= $segmentToAppend;
|
||||
|
||||
return $segment;
|
||||
}
|
||||
|
||||
protected function getNumeric($idSite, $period, $date, $segment, $toFetch)
|
||||
|
|
@ -416,7 +501,9 @@ class API extends \Piwik\Plugin\API
|
|||
*/
|
||||
public function getConversionRate($idSite, $period, $date, $segment = false, $idGoal = false)
|
||||
{
|
||||
return $this->getNumeric($idSite, $period, $date, $segment, Archiver::getRecordName('conversion_rate', $idGoal));
|
||||
$table = $this->get($idSite, $period, $date, $segment, $idGoal, 'conversion_rate');
|
||||
$table->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, array(new ConversionRate()));
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -474,9 +561,9 @@ class API extends \Piwik\Plugin\API
|
|||
$dataTable = $this->getGoalSpecificDataTable(
|
||||
Archiver::DAYS_UNTIL_CONV_RECORD_NAME, $idSite, $period, $date, $segment, $idGoal);
|
||||
|
||||
$dataTable->queueFilter('Sort', array('label', 'asc', true));
|
||||
$dataTable->queueFilter('Sort', array('label', 'asc', true, false));
|
||||
$dataTable->queueFilter(
|
||||
'BeautifyRangeLabels', array(Piwik::translate('General_OneDay'), Piwik::translate('General_NDays')));
|
||||
'BeautifyRangeLabels', array(Piwik::translate('Intl_OneDay'), Piwik::translate('Intl_NDays')));
|
||||
|
||||
return $dataTable;
|
||||
}
|
||||
|
|
@ -498,7 +585,7 @@ class API extends \Piwik\Plugin\API
|
|||
$dataTable = $this->getGoalSpecificDataTable(
|
||||
Archiver::VISITS_UNTIL_RECORD_NAME, $idSite, $period, $date, $segment, $idGoal);
|
||||
|
||||
$dataTable->queueFilter('Sort', array('label', 'asc', true));
|
||||
$dataTable->queueFilter('Sort', array('label', 'asc', true, false));
|
||||
$dataTable->queueFilter(
|
||||
'BeautifyRangeLabels', array(Piwik::translate('General_OneVisit'), Piwik::translate('General_NVisits')));
|
||||
|
||||
|
|
@ -564,4 +651,15 @@ class API extends \Piwik\Plugin\API
|
|||
$this->renameNotDefinedRow($dataTable, $notDefinedStringPretty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function getCacheId($idSite)
|
||||
{
|
||||
return CacheId::pluginAware('Goals.getGoals.' . $idSite);
|
||||
}
|
||||
|
||||
private function getGoalsInfoStaticCache()
|
||||
{
|
||||
return PiwikCache::getTransientCache();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -13,8 +13,6 @@ use Piwik\DataAccess\LogAggregator;
|
|||
use Piwik\DataArray;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\PluginsArchiver;
|
||||
use Piwik\PluginsManager;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
|
||||
class Archiver extends \Piwik\Plugin\Archiver
|
||||
|
|
@ -156,7 +154,6 @@ class Archiver extends \Piwik\Plugin\Archiver
|
|||
// Stats for all goals
|
||||
$nbConvertedVisits = $this->getProcessor()->getNumberOfVisitsConverted();
|
||||
$metrics = array(
|
||||
self::getRecordName('conversion_rate') => $this->getConversionRate($nbConvertedVisits),
|
||||
self::getRecordName('nb_conversions') => $totalConversions,
|
||||
self::getRecordName('nb_visits_converted') => $nbConvertedVisits,
|
||||
self::getRecordName('revenue') => $totalRevenue,
|
||||
|
|
@ -174,11 +171,6 @@ class Archiver extends \Piwik\Plugin\Archiver
|
|||
$recordName = self::getRecordName($metricName, $idGoal);
|
||||
$numericRecords[$recordName] = $value;
|
||||
}
|
||||
if (!empty($array[Metrics::INDEX_GOAL_NB_VISITS_CONVERTED])) {
|
||||
$conversion_rate = $this->getConversionRate($array[Metrics::INDEX_GOAL_NB_VISITS_CONVERTED]);
|
||||
$recordName = self::getRecordName('conversion_rate', $idGoal);
|
||||
$numericRecords[$recordName] = $conversion_rate;
|
||||
}
|
||||
}
|
||||
return $numericRecords;
|
||||
}
|
||||
|
|
@ -188,7 +180,7 @@ class Archiver extends \Piwik\Plugin\Archiver
|
|||
* @param int|bool $idGoal idGoal to return the metrics for, or false to return overall
|
||||
* @return string Archive record name
|
||||
*/
|
||||
static public function getRecordName($recordName, $idGoal = false)
|
||||
public static function getRecordName($recordName, $idGoal = false)
|
||||
{
|
||||
$idGoalStr = '';
|
||||
if ($idGoal !== false) {
|
||||
|
|
@ -197,12 +189,6 @@ class Archiver extends \Piwik\Plugin\Archiver
|
|||
return 'Goal_' . $idGoalStr . $recordName;
|
||||
}
|
||||
|
||||
protected function getConversionRate($count)
|
||||
{
|
||||
$visits = $this->getProcessor()->getNumberOfVisits();
|
||||
return round(100 * $count / $visits, GoalManager::REVENUE_PRECISION);
|
||||
}
|
||||
|
||||
protected function insertReports($recordName, $visitsToConversions)
|
||||
{
|
||||
foreach ($visitsToConversions as $idGoal => $table) {
|
||||
|
|
@ -358,7 +344,7 @@ class Archiver extends \Piwik\Plugin\Archiver
|
|||
return array(GoalManager::IDGOAL_CART, GoalManager::IDGOAL_ORDER);
|
||||
}
|
||||
|
||||
static public function getItemRecordNameAbandonedCart($recordName)
|
||||
public static function getItemRecordNameAbandonedCart($recordName)
|
||||
{
|
||||
return $recordName . '_Cart';
|
||||
}
|
||||
|
|
@ -375,7 +361,15 @@ class Archiver extends \Piwik\Plugin\Archiver
|
|||
foreach ($this->dimensionRecord as $recordName) {
|
||||
$dataTableToSum[] = self::getItemRecordNameAbandonedCart($recordName);
|
||||
}
|
||||
$this->getProcessor()->aggregateDataTableRecords($dataTableToSum);
|
||||
$columnsAggregationOperation = null;
|
||||
|
||||
$this->getProcessor()->aggregateDataTableRecords($dataTableToSum,
|
||||
$maximumRowsInDataTableLevelZero = null,
|
||||
$maximumRowsInSubDataTable = null,
|
||||
$columnToSortByBeforeTruncation = null,
|
||||
$columnsAggregationOperation,
|
||||
$columnsToRenameAfterAggregation = null,
|
||||
$countRowsRecursive = array());
|
||||
|
||||
/*
|
||||
* Archive General Goal metrics
|
||||
|
|
@ -391,28 +385,37 @@ class Archiver extends \Piwik\Plugin\Archiver
|
|||
$fieldsToSum = array();
|
||||
foreach ($goalIdsToSum as $goalId) {
|
||||
$metricsToSum = Goals::getGoalColumns($goalId);
|
||||
unset($metricsToSum[array_search('conversion_rate', $metricsToSum)]);
|
||||
foreach ($metricsToSum as $metricName) {
|
||||
$fieldsToSum[] = self::getRecordName($metricName, $goalId);
|
||||
}
|
||||
}
|
||||
$records = $this->getProcessor()->aggregateNumericMetrics($fieldsToSum);
|
||||
$this->getProcessor()->aggregateNumericMetrics($fieldsToSum);
|
||||
|
||||
$columnsAggregationOperation = null;
|
||||
|
||||
// also recording conversion_rate for each goal
|
||||
foreach ($goalIdsToSum as $goalId) {
|
||||
$nb_conversions = $records[self::getRecordName('nb_visits_converted', $goalId)];
|
||||
$conversion_rate = $this->getConversionRate($nb_conversions);
|
||||
$this->getProcessor()->insertNumericRecord(self::getRecordName('conversion_rate', $goalId), $conversion_rate);
|
||||
|
||||
// sum up the visits to conversion data table & the days to conversion data table
|
||||
$this->getProcessor()->aggregateDataTableRecords(array(
|
||||
self::getRecordName(self::VISITS_UNTIL_RECORD_NAME, $goalId),
|
||||
self::getRecordName(self::DAYS_UNTIL_CONV_RECORD_NAME, $goalId)));
|
||||
$this->getProcessor()->aggregateDataTableRecords(
|
||||
array(self::getRecordName(self::VISITS_UNTIL_RECORD_NAME, $goalId),
|
||||
self::getRecordName(self::DAYS_UNTIL_CONV_RECORD_NAME, $goalId)),
|
||||
$maximumRowsInDataTableLevelZero = null,
|
||||
$maximumRowsInSubDataTable = null,
|
||||
$columnToSortByBeforeTruncation = null,
|
||||
$columnsAggregationOperation,
|
||||
$columnsToRenameAfterAggregation = null,
|
||||
$countRowsRecursive = array());
|
||||
}
|
||||
|
||||
$columnsAggregationOperation = null;
|
||||
// sum up goal overview reports
|
||||
$this->getProcessor()->aggregateDataTableRecords(array(
|
||||
self::getRecordName(self::VISITS_UNTIL_RECORD_NAME),
|
||||
self::getRecordName(self::DAYS_UNTIL_CONV_RECORD_NAME)));
|
||||
$this->getProcessor()->aggregateDataTableRecords(
|
||||
array(self::getRecordName(self::VISITS_UNTIL_RECORD_NAME),
|
||||
self::getRecordName(self::DAYS_UNTIL_CONV_RECORD_NAME)),
|
||||
$maximumRowsInDataTableLevelZero = null,
|
||||
$maximumRowsInSubDataTable = null,
|
||||
$columnToSortByBeforeTruncation = null,
|
||||
$columnsAggregationOperation,
|
||||
$columnsToRenameAfterAggregation = null,
|
||||
$countRowsRecursive = array());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
www/analytics/plugins/Goals/Columns/DaysToConversion.php
Normal file
20
www/analytics/plugins/Goals/Columns/DaysToConversion.php
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?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\Goals\Columns;
|
||||
|
||||
use Piwik\Columns\Dimension;
|
||||
use Piwik\Piwik;
|
||||
|
||||
class DaysToConversion extends Dimension
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return Piwik::translate('Goals_DaysToConv');
|
||||
}
|
||||
}
|
||||
33
www/analytics/plugins/Goals/Columns/IdGoal.php
Normal file
33
www/analytics/plugins/Goals/Columns/IdGoal.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?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\Goals\Columns;
|
||||
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\Dimension\ConversionDimension;
|
||||
use Piwik\Plugin\Segment;
|
||||
|
||||
class IdGoal extends ConversionDimension
|
||||
{
|
||||
protected $columnName = 'idgoal';
|
||||
|
||||
protected function configureSegments()
|
||||
{
|
||||
$segment = new Segment();
|
||||
$segment->setCategory('General_Visit');
|
||||
$segment->setName('General_VisitConvertedGoalId');
|
||||
$segment->setSegment('visitConvertedGoalId');
|
||||
$segment->setAcceptedValues('1, 2, 3, etc.');
|
||||
$this->addSegment($segment);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return Piwik::translate('General_VisitConvertedGoalId');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?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\Goals\Columns\Metrics;
|
||||
|
||||
use Piwik\Archive\DataTableFactory;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\ProcessedMetric;
|
||||
|
||||
/**
|
||||
* The average value for each order. Calculated as:
|
||||
*
|
||||
* revenue / nb_conversions
|
||||
*
|
||||
* revenue & nb_conversions are calculated by the Goals archiver.
|
||||
*/
|
||||
class AverageOrderRevenue extends ProcessedMetric
|
||||
{
|
||||
private $idSite;
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'avg_order_revenue';
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$revenue = $this->getMetric($row, 'revenue');
|
||||
$conversions = $this->getMetric($row, 'nb_conversions');
|
||||
|
||||
return Piwik::getQuotientSafe($revenue, $conversions, $precision = 2);
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('General_AverageOrderValue');
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('revenue', 'nb_conversions');
|
||||
}
|
||||
|
||||
public function format($value, Formatter $formatter)
|
||||
{
|
||||
return $formatter->getPrettyMoney($value, $this->idSite);
|
||||
}
|
||||
|
||||
public function beforeFormat($report, DataTable $table)
|
||||
{
|
||||
$this->idSite = DataTableFactory::getSiteIdFromMetadata($table);
|
||||
return !empty($this->idSite); // skip formatting if there is no site to get currency info from
|
||||
}
|
||||
}
|
||||
64
www/analytics/plugins/Goals/Columns/Metrics/AveragePrice.php
Normal file
64
www/analytics/plugins/Goals/Columns/Metrics/AveragePrice.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?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\Goals\Columns\Metrics;
|
||||
|
||||
use Piwik\Archive\DataTableFactory;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\ProcessedMetric;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
|
||||
/**
|
||||
* The average price for each ecommerce order or abandoned cart. Calculated as:
|
||||
*
|
||||
* price / (orders or abandoned_carts)
|
||||
*
|
||||
* price, orders and abandoned_carts are calculated by the Goals archiver.
|
||||
*/
|
||||
class AveragePrice extends ProcessedMetric
|
||||
{
|
||||
private $idSite;
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'avg_price';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('General_AveragePrice');
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$price = $this->getMetric($row, 'price');
|
||||
$orders = $this->getMetric($row, 'orders');
|
||||
$abandonedCarts = $this->getMetric($row, 'abandoned_carts');
|
||||
|
||||
return Piwik::getQuotientSafe($price, $orders === false ? $abandonedCarts : $orders, GoalManager::REVENUE_PRECISION);
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('price', 'orders', 'abandoned_carts');
|
||||
}
|
||||
|
||||
public function format($value, Formatter $formatter)
|
||||
{
|
||||
return $formatter->getPrettyMoney($value, $this->idSite);
|
||||
}
|
||||
|
||||
public function beforeFormat($report, DataTable $table)
|
||||
{
|
||||
$this->idSite = DataTableFactory::getSiteIdFromMetadata($table);
|
||||
return !empty($this->idSite); // skip formatting if there is no site to get currency info from
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?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\Goals\Columns\Metrics;
|
||||
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\ProcessedMetric;
|
||||
|
||||
/**
|
||||
* The average amount of products in each order or abandoned cart. Calculated as:
|
||||
*
|
||||
* quantity / (orders or abandoned_carts)
|
||||
*
|
||||
* quantity, orders and abandoned_carts are calculated by the Goals archiver.
|
||||
*/
|
||||
class AverageQuantity extends ProcessedMetric
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'avg_quantity';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('General_AverageQuantity');
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$quantity = $this->getMetric($row, 'quantity');
|
||||
$orders = $this->getMetric($row, 'orders');
|
||||
$abandonedCarts = $this->getMetric($row, 'abandoned_carts');
|
||||
|
||||
return Piwik::getQuotientSafe($quantity, $orders === false ? $abandonedCarts : $orders, $precision = 1);
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('quantity', 'orders', 'abandoned_carts');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?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\Goals\Columns\Metrics\GoalSpecific;
|
||||
|
||||
use Piwik\Archive\DataTableFactory;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\Goals\Columns\Metrics\GoalSpecificProcessedMetric;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
|
||||
/**
|
||||
* The average order revenue for a specific goal. Calculated as:
|
||||
*
|
||||
* goals' revenue / goal's nb_conversions
|
||||
*/
|
||||
class AverageOrderRevenue extends GoalSpecificProcessedMetric
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return $this->getColumnPrefix() . '_avg_order_revenue';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('General_AverageOrderValue');
|
||||
}
|
||||
|
||||
public function getDocumentation()
|
||||
{
|
||||
return Piwik::translate('Goals_ColumnAverageOrderRevenueDocumentation', $this->getGoalNameForDocs());
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('goals');
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$mappingFromNameToIdGoal = Metrics::getMappingFromNameToIdGoal();
|
||||
|
||||
$goalMetrics = $this->getGoalMetrics($row);
|
||||
|
||||
$goalRevenue = $this->getMetric($goalMetrics, 'revenue', $mappingFromNameToIdGoal);
|
||||
$conversions = $this->getMetric($goalMetrics, 'nb_conversions', $mappingFromNameToIdGoal);
|
||||
|
||||
return Piwik::getQuotientSafe($goalRevenue, $conversions, GoalManager::REVENUE_PRECISION);
|
||||
}
|
||||
|
||||
public function format($value, Formatter $formatter)
|
||||
{
|
||||
return $formatter->getPrettyMoney($value, $this->idSite);
|
||||
}
|
||||
|
||||
public function beforeFormat($report, DataTable $table)
|
||||
{
|
||||
$this->idSite = DataTableFactory::getSiteIdFromMetadata($table);
|
||||
return !empty($this->idSite); // skip formatting if there is no site to get currency info from
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?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\Goals\Columns\Metrics\GoalSpecific;
|
||||
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\Goals\Columns\Metrics\GoalSpecificProcessedMetric;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
|
||||
/**
|
||||
* The conversion rate for a specific goal. Calculated as:
|
||||
*
|
||||
* goal's nb_conversions / nb_visits
|
||||
*
|
||||
* The goal's nb_conversions is calculated by the Goal archiver and nb_visits
|
||||
* by the core archiving process.
|
||||
*/
|
||||
class ConversionRate extends GoalSpecificProcessedMetric
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return $this->getColumnPrefix() . '_conversion_rate';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('Goals_ConversionRate', $this->getGoalName());
|
||||
}
|
||||
|
||||
public function getDocumentation()
|
||||
{
|
||||
return Piwik::translate('Goals_ColumnConversionRateDocumentation', $this->getGoalNameForDocs());
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('goals');
|
||||
}
|
||||
|
||||
public function format($value, Formatter $formatter)
|
||||
{
|
||||
return $formatter->getPrettyPercentFromQuotient($value);
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$mappingFromNameToIdGoal = Metrics::getMappingFromNameToIdGoal();
|
||||
|
||||
$goalMetrics = $this->getGoalMetrics($row);
|
||||
|
||||
$nbVisits = $this->getMetric($row, 'nb_visits');
|
||||
$conversions = $this->getMetric($goalMetrics, 'nb_conversions', $mappingFromNameToIdGoal);
|
||||
|
||||
return Piwik::getQuotientSafe($conversions, $nbVisits, GoalManager::REVENUE_PRECISION + 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?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\Goals\Columns\Metrics\GoalSpecific;
|
||||
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\Goals\Columns\Metrics\GoalSpecificProcessedMetric;
|
||||
|
||||
/**
|
||||
* The conversions for a specific goal. Returns the conversions for a single goal which
|
||||
* is then treated as a new column.
|
||||
*/
|
||||
class Conversions extends GoalSpecificProcessedMetric
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return $this->getColumnPrefix() . '_nb_conversions';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('Goals_Conversions', $this->getGoalNameForDocs());
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('goals');
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$mappingFromNameToIdGoal = Metrics::getMappingFromNameToIdGoal();
|
||||
|
||||
$goalMetrics = $this->getGoalMetrics($row);
|
||||
return (int) $this->getMetric($goalMetrics, 'nb_conversions', $mappingFromNameToIdGoal);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?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\Goals\Columns\Metrics\GoalSpecific;
|
||||
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\Goals\Columns\Metrics\GoalSpecificProcessedMetric;
|
||||
|
||||
/**
|
||||
* The number of ecommerce order items for conversions of a goal. Returns the 'items'
|
||||
* goal specific metric.
|
||||
*/
|
||||
class ItemsCount extends GoalSpecificProcessedMetric
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return $this->getColumnPrefix() . '_items';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('General_PurchasedProducts');
|
||||
}
|
||||
|
||||
public function getDocumentation()
|
||||
{
|
||||
return Piwik::translate('Goals_ColumnPurchasedProductsDocumentation', $this->getGoalNameForDocs());
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('goals');
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$mappingFromNameToIdGoal = Metrics::getMappingFromNameToIdGoal();
|
||||
|
||||
$goalMetrics = $this->getGoalMetrics($row);
|
||||
return (int) $this->getMetric($goalMetrics, 'items', $mappingFromNameToIdGoal);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?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\Goals\Columns\Metrics\GoalSpecific;
|
||||
|
||||
use Piwik\Archive\DataTableFactory;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\Goals\Columns\Metrics\GoalSpecificProcessedMetric;
|
||||
|
||||
/**
|
||||
* Revenue for a specific goal.
|
||||
*/
|
||||
class Revenue extends GoalSpecificProcessedMetric
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return $this->getColumnPrefix() . '_revenue';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('%s ' . Piwik::translate('General_ColumnRevenue'), $this->getGoalName());
|
||||
}
|
||||
|
||||
public function getDocumentation()
|
||||
{
|
||||
return Piwik::translate('Goals_ColumnRevenueDocumentation', $this->getGoalNameForDocs());
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('goals');
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$mappingFromNameToIdGoal = Metrics::getMappingFromNameToIdGoal();
|
||||
|
||||
$goalMetrics = $this->getGoalMetrics($row);
|
||||
return (float) $this->getMetric($goalMetrics, 'revenue', $mappingFromNameToIdGoal);
|
||||
}
|
||||
|
||||
public function format($value, Formatter $formatter)
|
||||
{
|
||||
return $formatter->getPrettyMoney($value, $this->idSite);
|
||||
}
|
||||
|
||||
public function beforeFormat($report, DataTable $table)
|
||||
{
|
||||
$this->idSite = DataTableFactory::getSiteIdFromMetadata($table);
|
||||
return !empty($this->idSite); // skip formatting if there is no site to get currency info from
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<?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\Goals\Columns\Metrics\GoalSpecific;
|
||||
|
||||
use Piwik\Archive\DataTableFactory;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\Goals\Columns\Metrics\GoalSpecificProcessedMetric;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
|
||||
/**
|
||||
* Revenue per visit for a specific goal. Calculated as:
|
||||
*
|
||||
* goal's revenue / (nb_visits or goal's nb_conversions depending on what is present in data)
|
||||
*
|
||||
* Goal revenue & nb_conversion are calculated by the Goals archiver.
|
||||
*/
|
||||
class RevenuePerVisit extends GoalSpecificProcessedMetric
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return $this->getColumnPrefix() . '_revenue_per_visit';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return $this->getGoalName() . ' ' . Piwik::translate('General_ColumnValuePerVisit');
|
||||
}
|
||||
|
||||
public function getDocumentation()
|
||||
{
|
||||
if ($this->idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
|
||||
return Piwik::translate('Goals_ColumnAverageOrderRevenueDocumentation', $this->getGoalNameForDocs());
|
||||
} else {
|
||||
return Piwik::translate('Goals_ColumnRevenuePerVisitDocumentation', Piwik::translate('Goals_EcommerceAndGoalsMenu'));
|
||||
}
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('goals', 'nb_visits');
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$mappingFromNameToIdGoal = Metrics::getMappingFromNameToIdGoal();
|
||||
|
||||
$goalMetrics = $this->getGoalMetrics($row);
|
||||
|
||||
$nbVisits = $this->getMetric($row, 'nb_visits');
|
||||
$conversions = $this->getMetric($goalMetrics, 'nb_conversions', $mappingFromNameToIdGoal);
|
||||
|
||||
$goalRevenue = (float) $this->getMetric($goalMetrics, 'revenue', $mappingFromNameToIdGoal);
|
||||
|
||||
return Piwik::getQuotientSafe($goalRevenue, $nbVisits == 0 ? $conversions : $nbVisits, GoalManager::REVENUE_PRECISION);
|
||||
}
|
||||
|
||||
public function format($value, Formatter $formatter)
|
||||
{
|
||||
return $formatter->getPrettyMoney($value, $this->idSite);
|
||||
}
|
||||
|
||||
public function beforeFormat($report, DataTable $table)
|
||||
{
|
||||
$this->idSite = DataTableFactory::getSiteIdFromMetadata($table);
|
||||
return !empty($this->idSite); // skip formatting if there is no site to get currency info from
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
<?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\Goals\Columns\Metrics;
|
||||
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\ProcessedMetric;
|
||||
use Piwik\Plugins\Goals\API as GoalsAPI;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
|
||||
/**
|
||||
* Base class for processed metrics that are calculated using metrics that are
|
||||
* specific to certain goals.
|
||||
*/
|
||||
abstract class GoalSpecificProcessedMetric extends ProcessedMetric
|
||||
{
|
||||
/**
|
||||
* The ID of the goal to calculate metrics for.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $idGoal;
|
||||
|
||||
/**
|
||||
* The ID of the site the goal belongs to.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $idSite;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int|null $idSite The ID of the site the goal belongs to. If supplied, affects the formatting
|
||||
* and translated name of the metric.
|
||||
* @param int $idGoal The ID of the goal to calculate metrics for.
|
||||
*/
|
||||
public function __construct($idSite, $idGoal)
|
||||
{
|
||||
$this->idSite = $idSite;
|
||||
$this->idGoal = $idGoal;
|
||||
}
|
||||
|
||||
protected function getColumnPrefix()
|
||||
{
|
||||
return 'goal_' . $this->idGoal;
|
||||
}
|
||||
|
||||
protected function getGoalMetrics(Row $row)
|
||||
{
|
||||
$allGoalMetrics = $this->getMetric($row, 'goals');
|
||||
if (isset($allGoalMetrics[$this->idGoal])) {
|
||||
return $allGoalMetrics[$this->idGoal];
|
||||
} else {
|
||||
$alternateKey = 'idgoal=' . $this->idGoal;
|
||||
if (isset($allGoalMetrics[$alternateKey])) {
|
||||
return $allGoalMetrics[$alternateKey];
|
||||
} elseif ($this->idGoal === Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
|
||||
$alternateKey = GoalManager::IDGOAL_ORDER;
|
||||
if (isset($allGoalMetrics[$alternateKey])) {
|
||||
return $allGoalMetrics[$alternateKey];
|
||||
}
|
||||
} elseif ($this->idGoal === Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART) {
|
||||
$alternateKey = GoalManager::IDGOAL_CART;
|
||||
if (isset($allGoalMetrics[$alternateKey])) {
|
||||
return $allGoalMetrics[$alternateKey];
|
||||
}
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getGoalName()
|
||||
{
|
||||
if ($this->idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
|
||||
return Piwik::translate('Goals_EcommerceOrder');
|
||||
}
|
||||
|
||||
if (isset($this->idSite)) {
|
||||
$allGoals = GoalsAPI::getInstance()->getGoals($this->idSite);
|
||||
$goalName = @$allGoals[$this->idGoal]['name'];
|
||||
return Common::sanitizeInputValue($goalName);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
protected function getGoalNameForDocs()
|
||||
{
|
||||
$goalName = $this->getGoalName();
|
||||
if ($goalName == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
|
||||
$goalName = '"' . $goalName . '"';
|
||||
}
|
||||
return $goalName;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?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\Goals\Columns\Metrics;
|
||||
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\ProcessedMetric;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
|
||||
/**
|
||||
* The conversion rate for ecommerce orders. Calculated as:
|
||||
*
|
||||
* (orders or abandoned_carts) / nb_visits
|
||||
*
|
||||
* orders and abandoned_carts are calculated by the Goals archiver.
|
||||
*/
|
||||
class ProductConversionRate extends ProcessedMetric
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'conversion_rate';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('General_ProductConversionRate');
|
||||
}
|
||||
|
||||
public function format($value, Formatter $formatter)
|
||||
{
|
||||
return $formatter->getPrettyPercentFromQuotient($value);
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$orders = $this->getMetric($row, 'orders');
|
||||
$abandonedCarts = $this->getMetric($row, 'abandoned_carts');
|
||||
$visits = $this->getMetric($row, 'nb_visits');
|
||||
|
||||
return Piwik::getQuotientSafe($orders === false ? $abandonedCarts : $orders, $visits, GoalManager::REVENUE_PRECISION + 2);
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('orders', 'abandoned_carts', 'nb_visits');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<?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\Goals\Columns\Metrics;
|
||||
|
||||
use Piwik\Archive\DataTableFactory;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\ProcessedMetric;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
|
||||
/**
|
||||
* The amount of revenue per visit (or per conversion if there are no visits). Calculated as:
|
||||
*
|
||||
* sum(revenue for all goals) / (nb_visits or nb_conversions if no visits)
|
||||
*
|
||||
* Goal revenue and nb_visits & nb_conversions are calculated by the archiving process.
|
||||
*/
|
||||
class RevenuePerVisit extends ProcessedMetric
|
||||
{
|
||||
private $idSite;
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'revenue_per_visit';
|
||||
}
|
||||
|
||||
public function getTranslatedName()
|
||||
{
|
||||
return Piwik::translate('General_ColumnValuePerVisit');
|
||||
}
|
||||
|
||||
public function getDependentMetrics()
|
||||
{
|
||||
return array('revenue', 'nb_visits', 'nb_conversions','goals');
|
||||
}
|
||||
|
||||
public function compute(Row $row)
|
||||
{
|
||||
$mappingFromNameToIdGoal = Metrics::getMappingFromNameToIdGoal();
|
||||
$goals = $this->getMetric($row, 'goals') ?: array();
|
||||
|
||||
$revenue = 0;
|
||||
foreach ($goals as $goalId => $goalMetrics) {
|
||||
if ($goalId == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART) {
|
||||
continue;
|
||||
}
|
||||
if ($goalId >= GoalManager::IDGOAL_ORDER
|
||||
|| $goalId == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER
|
||||
) {
|
||||
$revenue += (int) $this->getMetric($goalMetrics, 'revenue', $mappingFromNameToIdGoal);
|
||||
}
|
||||
}
|
||||
|
||||
if ($revenue == 0) {
|
||||
$revenue = (int) $this->getMetric($row, 'revenue');
|
||||
}
|
||||
|
||||
$nbVisits = (int) $this->getMetric($row, 'nb_visits');
|
||||
$conversions = (int) $this->getMetric($row, 'nb_conversions');
|
||||
|
||||
// If no visit for this metric, but some conversions, we still want to display some kind of "revenue per visit"
|
||||
// even though it will actually be in this edge case "Revenue per conversion"
|
||||
return Piwik::getQuotientSafe($revenue, $nbVisits == 0 ? $conversions : $nbVisits, GoalManager::REVENUE_PRECISION);
|
||||
}
|
||||
|
||||
public function format($value, Formatter $formatter)
|
||||
{
|
||||
return $formatter->getPrettyMoney($value, $this->idSite);
|
||||
}
|
||||
|
||||
public function beforeFormat($report, DataTable $table)
|
||||
{
|
||||
$this->idSite = DataTableFactory::getSiteIdFromMetadata($table);
|
||||
return !empty($this->idSite); // skip formatting if there is no site to get currency info from
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?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\Goals\Columns;
|
||||
|
||||
use Piwik\Columns\Dimension;
|
||||
use Piwik\Piwik;
|
||||
|
||||
class VisitsUntilConversion extends Dimension
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return Piwik::translate('Goals_VisitsUntilConv');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -8,17 +8,15 @@
|
|||
*/
|
||||
namespace Piwik\Plugins\Goals;
|
||||
|
||||
use Exception;
|
||||
use Piwik\API\Request;
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable\Filter\AddColumnsProcessedMetricsGoal;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\FrontController;
|
||||
use Piwik\DataTable\Filter\AddColumnsProcessedMetricsGoal;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\Referrers\API as APIReferrers;
|
||||
use Piwik\View\ReportsByDimension;
|
||||
use Piwik\Translation\Translator;
|
||||
use Piwik\View;
|
||||
use Piwik\ViewDataTable\Factory;
|
||||
use Piwik\View\ReportsByDimension;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -44,30 +42,42 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
'items' => 'General_PurchasedProducts',
|
||||
);
|
||||
|
||||
private function formatConversionRate($conversionRate)
|
||||
/**
|
||||
* @var Translator
|
||||
*/
|
||||
private $translator;
|
||||
|
||||
/**
|
||||
* @var TranslationHelper
|
||||
*/
|
||||
private $translationHelper;
|
||||
|
||||
private function formatConversionRate($conversionRate, $columnName = 'conversion_rate')
|
||||
{
|
||||
if ($conversionRate instanceof DataTable) {
|
||||
if ($conversionRate->getRowsCount() == 0) {
|
||||
$conversionRate = 0;
|
||||
} else {
|
||||
$columns = $conversionRate->getFirstRow()->getColumns();
|
||||
$conversionRate = (float)reset($columns);
|
||||
$conversionRate = $conversionRate->getFirstRow()->getColumn($columnName);
|
||||
}
|
||||
}
|
||||
return sprintf('%.' . self::CONVERSION_RATE_PRECISION . 'f%%', $conversionRate);
|
||||
|
||||
if (!is_numeric($conversionRate)) {
|
||||
$conversionRate = sprintf('%.' . self::CONVERSION_RATE_PRECISION . 'f%%', $conversionRate);
|
||||
}
|
||||
|
||||
return $conversionRate;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
public function __construct(Translator $translator, TranslationHelper $translationHelper)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->translator = $translator;
|
||||
$this->translationHelper = $translationHelper;
|
||||
|
||||
$this->idSite = Common::getRequestVar('idSite', null, 'int');
|
||||
$this->goals = API::getInstance()->getGoals($this->idSite);
|
||||
foreach ($this->goals as &$goal) {
|
||||
$goal['name'] = Common::sanitizeInputValue($goal['name']);
|
||||
if (isset($goal['pattern'])) {
|
||||
$goal['pattern'] = Common::sanitizeInputValue($goal['pattern']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function widgetGoalReport()
|
||||
|
|
@ -84,39 +94,11 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
return $view->render();
|
||||
}
|
||||
|
||||
public function ecommerceReport()
|
||||
{
|
||||
if (!\Piwik\Plugin\Manager::getInstance()->isPluginActivated('CustomVariables')) {
|
||||
throw new Exception("Ecommerce Tracking requires that the plugin Custom Variables is enabled. Please enable the plugin CustomVariables (or ask your admin).");
|
||||
}
|
||||
|
||||
$view = $this->getGoalReportView($idGoal = Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER);
|
||||
$view->displayFullReport = true;
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
public function getEcommerceLog($fetch = false)
|
||||
{
|
||||
$saveGET = $_GET;
|
||||
$filterEcommerce = Common::getRequestVar('filterEcommerce', self::ECOMMERCE_LOG_SHOW_ORDERS, 'int');
|
||||
if($filterEcommerce == self::ECOMMERCE_LOG_SHOW_ORDERS) {
|
||||
$segment = urlencode('visitEcommerceStatus==ordered,visitEcommerceStatus==orderedThenAbandonedCart');
|
||||
} else {
|
||||
$segment = urlencode('visitEcommerceStatus==abandonedCart,visitEcommerceStatus==orderedThenAbandonedCart');
|
||||
}
|
||||
$_GET['segment'] = $segment;
|
||||
$_GET['filterEcommerce'] = $filterEcommerce;
|
||||
$_GET['widget'] = 1;
|
||||
$output = FrontController::getInstance()->dispatch('Live', 'getVisitorLog', array($fetch));
|
||||
$_GET = $saveGET;
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected function getGoalReportView($idGoal = false)
|
||||
{
|
||||
$view = new View('@Goals/getGoalReportView');
|
||||
if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
|
||||
$goalDefinition['name'] = Piwik::translate('Goals_Ecommerce');
|
||||
$goalDefinition['name'] = $this->translator->translate('Goals_Ecommerce');
|
||||
$goalDefinition['allow_multiple'] = true;
|
||||
$ecommerce = $view->ecommerce = true;
|
||||
} else {
|
||||
|
|
@ -137,20 +119,20 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
$view->$name = $value;
|
||||
}
|
||||
}
|
||||
$view->showHeadline = false;
|
||||
$view->idGoal = $idGoal;
|
||||
$view->goalName = $goalDefinition['name'];
|
||||
$view->goalAllowMultipleConversionsPerVisit = $goalDefinition['allow_multiple'];
|
||||
$view->graphEvolution = $this->getEvolutionGraph(array('nb_conversions'), $idGoal);
|
||||
$view->graphEvolution = $this->getEvolutionGraph(array(), $idGoal, array('nb_conversions'));
|
||||
$view->nameGraphEvolution = 'Goals.getEvolutionGraph' . $idGoal;
|
||||
$view->topDimensions = $this->getTopDimensions($idGoal);
|
||||
|
||||
$goalMetrics = Request::processRequest('Goals.get', array('idGoal' => $idGoal));
|
||||
|
||||
// conversion rate for new and returning visitors
|
||||
$segment = urldecode(\Piwik\Plugins\VisitFrequency\API::RETURNING_VISITOR_SEGMENT);
|
||||
$conversionRateReturning = API::getInstance()->getConversionRate($this->idSite, Common::getRequestVar('period'), Common::getRequestVar('date'), $segment, $idGoal);
|
||||
$view->conversion_rate_returning = $this->formatConversionRate($conversionRateReturning);
|
||||
$segment = 'visitorType==new';
|
||||
$conversionRateNew = API::getInstance()->getConversionRate($this->idSite, Common::getRequestVar('period'), Common::getRequestVar('date'), $segment, $idGoal);
|
||||
$view->conversion_rate_new = $this->formatConversionRate($conversionRateNew);
|
||||
$view->conversion_rate_returning = $this->formatConversionRate($goalMetrics, 'conversion_rate_returning_visit');
|
||||
$view->conversion_rate_new = $this->formatConversionRate($goalMetrics, 'conversion_rate_new_visit');
|
||||
|
||||
$view->goalReportsByDimension = $this->getGoalReportsByDimensionTable(
|
||||
$view->nb_conversions, isset($ecommerce), !empty($view->cart_nb_conversions));
|
||||
return $view;
|
||||
|
|
@ -163,20 +145,24 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
// unsanitize goal names and other text data (not done in API so as not to break
|
||||
// any other code/cause security issues)
|
||||
$goals = $this->goals;
|
||||
foreach ($goals as &$goal) {
|
||||
$goal['name'] = Common::unsanitizeInputValue($goal['name']);
|
||||
if (isset($goal['pattern'])) {
|
||||
$goal['pattern'] = Common::unsanitizeInputValue($goal['pattern']);
|
||||
}
|
||||
}
|
||||
$view->goalsJSON = Common::json_encode($goals);
|
||||
$view->goalsJSON = json_encode($goals);
|
||||
|
||||
$view->userCanEditGoals = Piwik::isUserHasAdminAccess($this->idSite);
|
||||
$view->ecommerceEnabled = $this->site->isEcommerceEnabled();
|
||||
$view->displayFullReport = true;
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
public function manage()
|
||||
{
|
||||
Piwik::checkUserHasAdminAccess($this->idSite);
|
||||
|
||||
$view = new View('@Goals/manageGoals');
|
||||
$this->setGeneralVariablesView($view);
|
||||
$this->setEditGoalsViewVariables($view);
|
||||
$this->setUserCanEditGoals($view);
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
public function widgetGoalsOverview()
|
||||
{
|
||||
$view = $this->getOverviewView();
|
||||
|
|
@ -189,7 +175,7 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
$view = new View('@Goals/getOverviewView');
|
||||
$this->setGeneralVariablesView($view);
|
||||
|
||||
$view->graphEvolution = $this->getEvolutionGraph(array('nb_conversions'));
|
||||
$view->graphEvolution = $this->getEvolutionGraph(array(), false, array('nb_conversions'));
|
||||
$view->nameGraphEvolution = 'GoalsgetEvolutionGraph';
|
||||
|
||||
// sparkline for the historical data of the above values
|
||||
|
|
@ -201,6 +187,7 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
$request = new Request("method=Goals.get&format=original&idGoal=");
|
||||
$datatable = $request->process();
|
||||
$dataRow = $datatable->getFirstRow();
|
||||
|
||||
$view->nb_conversions = $dataRow->getColumn('nb_conversions');
|
||||
$view->nb_visits_converted = $dataRow->getColumn('nb_visits_converted');
|
||||
$view->conversion_rate = $this->formatConversionRate($dataRow->getColumn('conversion_rate'));
|
||||
|
|
@ -242,19 +229,32 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
{
|
||||
$view = new View('@Goals/addNewGoal');
|
||||
$this->setGeneralVariablesView($view);
|
||||
$view->userCanEditGoals = Piwik::isUserHasAdminAccess($this->idSite);
|
||||
$this->setUserCanEditGoals($view);
|
||||
$view->onlyShowAddNewGoal = true;
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
public function getEvolutionGraph(array $columns = array(), $idGoal = false)
|
||||
public function editGoals()
|
||||
{
|
||||
$view = new View('@Goals/editGoals');
|
||||
$this->setGeneralVariablesView($view);
|
||||
$this->setEditGoalsViewVariables($view);
|
||||
$this->setUserCanEditGoals($view);
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
public function getEvolutionGraph(array $columns = array(), $idGoal = false, array $defaultColumns = array())
|
||||
{
|
||||
if (empty($columns)) {
|
||||
$columns = Common::getRequestVar('columns');
|
||||
$columns = Piwik::getArrayFromApiParameter($columns);
|
||||
$columns = Common::getRequestVar('columns', false);
|
||||
if (false !== $columns) {
|
||||
$columns = Piwik::getArrayFromApiParameter($columns);
|
||||
}
|
||||
}
|
||||
|
||||
$columns = !is_array($columns) ? array($columns) : $columns;
|
||||
if (false !== $columns) {
|
||||
$columns = !is_array($columns) ? array($columns) : $columns;
|
||||
}
|
||||
|
||||
if (empty($idGoal)) {
|
||||
$idGoal = Common::getRequestVar('idGoal', false, 'string');
|
||||
|
|
@ -266,10 +266,10 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
|
||||
$nameToLabel['nb_conversions'] = 'General_EcommerceOrders';
|
||||
} elseif ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART) {
|
||||
$nameToLabel['nb_conversions'] = Piwik::translate('General_VisitsWith', Piwik::translate('Goals_AbandonedCart'));
|
||||
$nameToLabel['nb_conversions'] = $this->translator->translate('General_VisitsWith', $this->translator->translate('Goals_AbandonedCart'));
|
||||
$nameToLabel['conversion_rate'] = $nameToLabel['nb_conversions'];
|
||||
$nameToLabel['revenue'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('General_ColumnRevenue'));
|
||||
$nameToLabel['items'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('Goals_Products'));
|
||||
$nameToLabel['revenue'] = $this->translator->translate('Goals_LeftInCart', $this->translator->translate('General_ColumnRevenue'));
|
||||
$nameToLabel['items'] = $this->translator->translate('Goals_LeftInCart', $this->translator->translate('Goals_Products'));
|
||||
}
|
||||
|
||||
$selectableColumns = array('nb_conversions', 'conversion_rate', 'revenue');
|
||||
|
|
@ -278,27 +278,33 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
$selectableColumns[] = 'avg_order_revenue';
|
||||
}
|
||||
|
||||
foreach (array_merge($columns, $selectableColumns) as $columnName) {
|
||||
foreach (array_merge($columns ? $columns : array(), $selectableColumns) as $columnName) {
|
||||
$columnTranslation = '';
|
||||
// find the right translation for this column, eg. find 'revenue' if column is Goal_1_revenue
|
||||
foreach ($nameToLabel as $metric => $metricTranslation) {
|
||||
if (strpos($columnName, $metric) !== false) {
|
||||
$columnTranslation = Piwik::translate($metricTranslation);
|
||||
$columnTranslation = $this->translator->translate($metricTranslation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($idGoal) && isset($this->goals[$idGoal])) {
|
||||
$goalName = $this->goals[$idGoal]['name'];
|
||||
$columnTranslation = "$columnTranslation (" . Piwik::translate('Goals_GoalX', "$goalName") . ")";
|
||||
$columnTranslation = "$columnTranslation (" . $this->translator->translate('Goals_GoalX', "$goalName") . ")";
|
||||
}
|
||||
$view->config->translations[$columnName] = $columnTranslation;
|
||||
}
|
||||
$view->config->columns_to_display = $columns;
|
||||
|
||||
if (!empty($columns)) {
|
||||
$view->config->columns_to_display = $columns;
|
||||
} elseif (empty($view->config->columns_to_display) && !empty($defaultColumns)) {
|
||||
$view->config->columns_to_display = $defaultColumns;
|
||||
}
|
||||
|
||||
$view->config->selectable_columns = $selectableColumns;
|
||||
|
||||
$langString = $idGoal ? 'Goals_SingleGoalOverviewDocumentation' : 'Goals_GoalsOverviewDocumentation';
|
||||
$view->config->documentation = Piwik::translate($langString, '<br />');
|
||||
$view->config->documentation = $this->translator->translate($langString, '<br />');
|
||||
|
||||
return $this->renderView($view);
|
||||
}
|
||||
|
|
@ -327,11 +333,11 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
$topDimensions = array();
|
||||
foreach ($topDimensionsToLoad as $dimensionName => $apiMethod) {
|
||||
$request = new Request("method=$apiMethod
|
||||
&format=original
|
||||
&filter_update_columns_when_show_all_goals=1
|
||||
&idGoal=" . AddColumnsProcessedMetricsGoal::GOALS_FULL_TABLE . "
|
||||
&filter_sort_order=desc
|
||||
&filter_sort_column=$columnNbConversions" .
|
||||
&format=original
|
||||
&filter_update_columns_when_show_all_goals=1
|
||||
&idGoal=" . AddColumnsProcessedMetricsGoal::GOALS_FULL_TABLE . "
|
||||
&filter_sort_order=desc
|
||||
&filter_sort_column=$columnNbConversions" .
|
||||
// select a couple more in case some are not valid (ie. conversions==0 or they are "Keyword not defined")
|
||||
"&filter_limit=" . (self::COUNT_TOP_ROWS_TO_DISPLAY + 2));
|
||||
$datatable = $request->process();
|
||||
|
|
@ -421,22 +427,13 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
$ecommerceCustomParams = array();
|
||||
if ($ecommerce) {
|
||||
if ($preloadAbandonedCart) {
|
||||
$ecommerceCustomParams['viewDataTable'] = 'ecommerceAbandonedCart';
|
||||
$ecommerceCustomParams['filterEcommerce'] = self::ECOMMERCE_LOG_SHOW_ABANDONED_CARTS;
|
||||
$ecommerceCustomParams['abandonedCarts'] = '1';
|
||||
} else {
|
||||
$ecommerceCustomParams['abandonedCarts'] = '0';
|
||||
}
|
||||
|
||||
$goalReportsByDimension->addReport(
|
||||
'Goals_EcommerceReports', 'Goals_ProductSKU', 'Goals.getItemsSku', $ecommerceCustomParams);
|
||||
$goalReportsByDimension->addReport(
|
||||
'Goals_EcommerceReports', 'Goals_ProductName', 'Goals.getItemsName', $ecommerceCustomParams);
|
||||
$goalReportsByDimension->addReport(
|
||||
'Goals_EcommerceReports', 'Goals_ProductCategory', 'Goals.getItemsCategory', $ecommerceCustomParams);
|
||||
|
||||
$goalReportsByDimension->addReport(
|
||||
'Goals_EcommerceReports', 'Goals_EcommerceLog', 'Goals.getEcommerceLog', $ecommerceCustomParams);
|
||||
}
|
||||
|
||||
if ($conversions > 0) {
|
||||
if ($conversions > 0 || $ecommerce) {
|
||||
// for non-Goals reports, we show the goals table
|
||||
$customParams = $ecommerceCustomParams + array('documentationForGoalsPage' => '1');
|
||||
|
||||
|
|
@ -447,15 +444,28 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
|
||||
$allReports = Goals::getReportsWithGoalMetrics();
|
||||
foreach ($allReports as $category => $reports) {
|
||||
$categoryText = Piwik::translate('Goals_ViewGoalsBy', $category);
|
||||
if ($ecommerce) {
|
||||
$categoryText = $this->translationHelper->translateEcommerceMetricCategory($category);
|
||||
} else {
|
||||
$categoryText = $this->translationHelper->translateGoalMetricCategory($category);
|
||||
}
|
||||
|
||||
foreach ($reports as $report) {
|
||||
if(empty($report['viewDataTable'])) {
|
||||
if (empty($report['viewDataTable'])
|
||||
&& empty($report['abandonedCarts'])
|
||||
) {
|
||||
$report['viewDataTable'] = 'tableGoals';
|
||||
}
|
||||
$customParams['viewDataTable'] = $report['viewDataTable'];
|
||||
|
||||
if (!empty($report['parameters'])) {
|
||||
$params = array_merge($customParams, $report['parameters']);
|
||||
} else {
|
||||
$params = $customParams;
|
||||
}
|
||||
|
||||
$goalReportsByDimension->addReport(
|
||||
$categoryText, $report['name'], $report['module'] . '.' . $report['action'], $customParams);
|
||||
$categoryText, $report['name'], $report['module'] . '.' . $report['action'], $params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -463,32 +473,32 @@ class Controller extends \Piwik\Plugin\Controller
|
|||
return $goalReportsByDimension->render();
|
||||
}
|
||||
|
||||
//
|
||||
// Report rendering actions
|
||||
//
|
||||
|
||||
public function getItemsSku()
|
||||
private function setEditGoalsViewVariables($view)
|
||||
{
|
||||
return $this->renderReport(__FUNCTION__);
|
||||
$goals = $this->goals;
|
||||
$view->goals = $goals;
|
||||
|
||||
$idGoal = Common::getRequestVar('idGoal', 0, 'int');
|
||||
$view->idGoal = 0;
|
||||
if ($idGoal && array_key_exists($idGoal, $goals)) {
|
||||
$view->idGoal = $idGoal;
|
||||
}
|
||||
|
||||
// unsanitize goal names and other text data (not done in API so as not to break
|
||||
// any other code/cause security issues)
|
||||
|
||||
foreach ($goals as &$goal) {
|
||||
$goal['name'] = Common::unsanitizeInputValue($goal['name']);
|
||||
if (isset($goal['pattern'])) {
|
||||
$goal['pattern'] = Common::unsanitizeInputValue($goal['pattern']);
|
||||
}
|
||||
}
|
||||
$view->goalsJSON = json_encode($goals);
|
||||
$view->ecommerceEnabled = $this->site->isEcommerceEnabled();
|
||||
}
|
||||
|
||||
public function getItemsName()
|
||||
private function setUserCanEditGoals(View $view)
|
||||
{
|
||||
return $this->renderReport(__FUNCTION__);
|
||||
}
|
||||
|
||||
public function getItemsCategory()
|
||||
{
|
||||
return $this->renderReport(__FUNCTION__);
|
||||
}
|
||||
|
||||
public function getVisitsUntilConversion()
|
||||
{
|
||||
return $this->renderReport(__FUNCTION__);
|
||||
}
|
||||
|
||||
public function getDaysToConversion()
|
||||
{
|
||||
return $this->renderReport(__FUNCTION__);
|
||||
$view->userCanEditGoals = Piwik::isUserHasAdminAccess($this->idSite);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
<?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\Goals\DataTable\Filter;
|
||||
|
||||
use Piwik\DataTable\BaseFilter;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Metrics;
|
||||
|
||||
/**
|
||||
* Appends a string to each column name in each row of a table. Please note this filter even appends the name to a
|
||||
* 'label' column. If you do not need this behaviour feel free to add a check to ignore label columns.
|
||||
*/
|
||||
class AppendNameToColumnNames extends BaseFilter
|
||||
{
|
||||
protected $nameToAppend;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param DataTable $table The table that will be eventually filtered.
|
||||
* @param string $nameToAppend The name that will be appended to each column
|
||||
*/
|
||||
public function __construct($table, $nameToAppend)
|
||||
{
|
||||
parent::__construct($table);
|
||||
$this->nameToAppend = $nameToAppend;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link ReplaceColumnNames}.
|
||||
*
|
||||
* @param DataTable $table
|
||||
*/
|
||||
public function filter($table)
|
||||
{
|
||||
if (!isset($this->nameToAppend) || '' === $this->nameToAppend || false === $this->nameToAppend) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($table->getRows() as $row) {
|
||||
$columns = $row->getColumns();
|
||||
|
||||
foreach ($columns as $column => $value) {
|
||||
$row->deleteColumn($column);
|
||||
$row->setColumn($column . $this->nameToAppend, $value);
|
||||
}
|
||||
|
||||
$this->filterSubTable($row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
* Piwik - free/libre analytics platform
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
|
|
@ -9,44 +9,27 @@
|
|||
namespace Piwik\Plugins\Goals;
|
||||
|
||||
use Piwik\ArchiveProcessor;
|
||||
|
||||
use Piwik\Common;
|
||||
use Piwik\Db;
|
||||
use Piwik\Menu\MenuMain;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\ViewDataTable;
|
||||
use Piwik\Site;
|
||||
use Piwik\Plugin\Report;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
use Piwik\Translate;
|
||||
use Piwik\WidgetsList;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Goals extends \Piwik\Plugin
|
||||
{
|
||||
public function getInformation()
|
||||
{
|
||||
$suffix = Piwik::translate('SitesManager_PiwikOffersEcommerceAnalytics',
|
||||
array('<a href="http://piwik.org/docs/ecommerce-analytics/" target="_blank">', '</a>'));
|
||||
$info = parent::getInformation();
|
||||
$info['description'] .= ' ' . $suffix;
|
||||
return $info;
|
||||
}
|
||||
|
||||
protected $ecommerceReports = array(
|
||||
array('Goals_ProductSKU', 'Goals', 'getItemsSku'),
|
||||
array('Goals_ProductName', 'Goals', 'getItemsName'),
|
||||
array('Goals_ProductCategory', 'Goals', 'getItemsCategory')
|
||||
);
|
||||
|
||||
static public function getReportsWithGoalMetrics()
|
||||
public static function getReportsWithGoalMetrics()
|
||||
{
|
||||
$dimensions = self::getAllReportsWithGoalMetrics();
|
||||
|
||||
$dimensionsByGroup = array();
|
||||
foreach ($dimensions as $dimension) {
|
||||
$group = $dimension['category'];
|
||||
// move "Custom Variables" report to the "Goals/Sales by User attribute" category
|
||||
if ($dimension['module'] === 'CustomVariables') {
|
||||
$group = 'VisitsSummary_VisitsSummary';
|
||||
}
|
||||
unset($dimension['category']);
|
||||
$dimensionsByGroup[$group][] = $dimension;
|
||||
}
|
||||
|
|
@ -57,22 +40,28 @@ class Goals extends \Piwik\Plugin
|
|||
|
||||
public static function sortGoalDimensionsByModule($a, $b)
|
||||
{
|
||||
$order = array(
|
||||
Piwik::translate('Referrers_Referrers'),
|
||||
Piwik::translate('General_Visit'),
|
||||
Piwik::translate('VisitTime_ColumnServerTime'),
|
||||
);
|
||||
static $order = null;
|
||||
|
||||
if (is_null($order)) {
|
||||
$order = array(
|
||||
'Referrers_Referrers',
|
||||
'General_Visit',
|
||||
'General_Visitors',
|
||||
'VisitsSummary_VisitsSummary',
|
||||
'VisitTime_ColumnServerTime',
|
||||
);
|
||||
}
|
||||
|
||||
$orderA = array_search($a, $order);
|
||||
$orderB = array_search($b, $order);
|
||||
return $orderA > $orderB;
|
||||
}
|
||||
|
||||
static public function getGoalColumns($idGoal)
|
||||
public static function getGoalColumns($idGoal)
|
||||
{
|
||||
$columns = array(
|
||||
'nb_conversions',
|
||||
'nb_visits_converted',
|
||||
'conversion_rate',
|
||||
'revenue',
|
||||
);
|
||||
if ($idGoal === false) {
|
||||
|
|
@ -95,38 +84,51 @@ class Goals extends \Piwik\Plugin
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Piwik\Plugin::getListHooksRegistered
|
||||
* @see Piwik\Plugin::registerEvents
|
||||
*/
|
||||
public function getListHooksRegistered()
|
||||
public function registerEvents()
|
||||
{
|
||||
$hooks = array(
|
||||
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
|
||||
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
|
||||
'Tracker.Cache.getSiteAttributes' => 'fetchGoalsFromDb',
|
||||
'API.getReportMetadata.end' => 'getReportMetadata',
|
||||
'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
|
||||
'WidgetsList.addWidgets' => 'addWidgets',
|
||||
'Menu.Reporting.addItems' => 'addMenus',
|
||||
'API.getReportMetadata.end' => 'getReportMetadataEnd',
|
||||
'SitesManager.deleteSite.end' => 'deleteSiteGoals',
|
||||
'Goals.getReportsWithGoalMetrics' => 'getActualReportsWithGoalMetrics',
|
||||
'ViewDataTable.configure' => 'configureViewDataTable',
|
||||
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
|
||||
'ViewDataTable.addViewDataTable' => 'getAvailableDataTableVisualizations'
|
||||
'Metrics.getDefaultMetricTranslations' => 'addMetricTranslations'
|
||||
);
|
||||
return $hooks;
|
||||
}
|
||||
|
||||
public function getAvailableDataTableVisualizations(&$visualizations)
|
||||
public function addMetricTranslations(&$translations)
|
||||
{
|
||||
$visualizations[] = 'Piwik\\Plugins\\Goals\\Visualizations\\Goals';
|
||||
$metrics = array(
|
||||
'orders' => 'General_EcommerceOrders',
|
||||
'ecommerce_revenue' => 'General_ProductRevenue',
|
||||
'revenue_per_visit' => 'General_ColumnValuePerVisit',
|
||||
'quantity' => 'General_Quantity',
|
||||
'avg_price' => 'General_AveragePrice',
|
||||
'avg_quantity' => 'General_AverageQuantity',
|
||||
'revenue_subtotal' => 'General_Subtotal',
|
||||
'revenue_tax' => 'General_Tax',
|
||||
'revenue_shipping' => 'General_Shipping',
|
||||
'revenue_discount' => 'General_Discount',
|
||||
'avg_order_revenue' => 'General_AverageOrderValue'
|
||||
);
|
||||
|
||||
$metrics = array_map(array('\\Piwik\\Piwik', 'translate'), $metrics);
|
||||
|
||||
$translations = array_merge($translations, $metrics);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete goals recorded for this site
|
||||
*/
|
||||
function deleteSiteGoals($idSite)
|
||||
public function deleteSiteGoals($idSite)
|
||||
{
|
||||
Db::query("DELETE FROM " . Common::prefixTable('goal') . " WHERE idsite = ? ", array($idSite));
|
||||
$model = new Model();
|
||||
$model->deleteGoalsForSite($idSite);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -136,10 +138,8 @@ class Goals extends \Piwik\Plugin
|
|||
*
|
||||
* Also, this will update metadata of all other reports that have Goal segmentation
|
||||
*/
|
||||
public function getReportMetadata(&$reports, $info)
|
||||
public function getReportMetadataEnd(&$reports, $info)
|
||||
{
|
||||
$idSites = $info['idSites'];
|
||||
|
||||
// Processed in AddColumnsProcessedMetricsGoal
|
||||
// These metrics will also be available for some reports, for each goal
|
||||
// Example: Conversion rate for Goal 2 for the keyword 'piwik'
|
||||
|
|
@ -148,210 +148,11 @@ class Goals extends \Piwik\Plugin
|
|||
);
|
||||
|
||||
$goalMetrics = array(
|
||||
'nb_conversions' => Piwik::translate('Goals_ColumnConversions'),
|
||||
'nb_visits_converted' => Piwik::translate('General_ColumnVisitsWithConversions'),
|
||||
'conversion_rate' => Piwik::translate('General_ColumnConversionRate'),
|
||||
'revenue' => Piwik::translate('General_ColumnRevenue')
|
||||
'nb_conversions' => Piwik::translate('Goals_ColumnConversions'),
|
||||
'conversion_rate' => Piwik::translate('General_ColumnConversionRate'),
|
||||
'revenue' => Piwik::translate('General_ColumnRevenue')
|
||||
);
|
||||
|
||||
$conversionReportMetrics = array(
|
||||
'nb_conversions' => Piwik::translate('Goals_ColumnConversions')
|
||||
);
|
||||
|
||||
// General Goal metrics: conversions, conv rate, revenue
|
||||
$goalsCategory = Piwik::translate('Goals_Goals');
|
||||
$reports[] = array(
|
||||
'category' => $goalsCategory,
|
||||
'name' => Piwik::translate('Goals_Goals'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'get',
|
||||
'metrics' => $goalMetrics,
|
||||
'processedMetrics' => array(),
|
||||
'order' => 1
|
||||
);
|
||||
|
||||
// If only one website is selected, we add the Goal metrics
|
||||
if (count($idSites) == 1) {
|
||||
$idSite = reset($idSites);
|
||||
$goals = API::getInstance()->getGoals($idSite);
|
||||
|
||||
// Add overall visits to conversion report
|
||||
$reports[] = array(
|
||||
'category' => $goalsCategory,
|
||||
'name' => Piwik::translate('Goals_VisitsUntilConv'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'getVisitsUntilConversion',
|
||||
'dimension' => Piwik::translate('Goals_VisitsUntilConv'),
|
||||
'constantRowsCount' => true,
|
||||
'parameters' => array(),
|
||||
'metrics' => $conversionReportMetrics,
|
||||
'order' => 5
|
||||
);
|
||||
|
||||
// Add overall days to conversion report
|
||||
$reports[] = array(
|
||||
'category' => $goalsCategory,
|
||||
'name' => Piwik::translate('Goals_DaysToConv'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'getDaysToConversion',
|
||||
'dimension' => Piwik::translate('Goals_DaysToConv'),
|
||||
'constantRowsCount' => true,
|
||||
'parameters' => array(),
|
||||
'metrics' => $conversionReportMetrics,
|
||||
'order' => 10
|
||||
);
|
||||
|
||||
foreach ($goals as $goal) {
|
||||
// Add the general Goal metrics: ie. total Goal conversions,
|
||||
// Goal conv rate or Goal total revenue.
|
||||
// This API call requires a custom parameter
|
||||
$goal['name'] = Common::sanitizeInputValue($goal['name']);
|
||||
$reports[] = array(
|
||||
'category' => $goalsCategory,
|
||||
'name' => Piwik::translate('Goals_GoalX', $goal['name']),
|
||||
'module' => 'Goals',
|
||||
'action' => 'get',
|
||||
'parameters' => array('idGoal' => $goal['idgoal']),
|
||||
'metrics' => $goalMetrics,
|
||||
'processedMetrics' => false,
|
||||
'order' => 50 + $goal['idgoal'] * 3
|
||||
);
|
||||
|
||||
// Add visits to conversion report
|
||||
$reports[] = array(
|
||||
'category' => $goalsCategory,
|
||||
'name' => $goal['name'] . ' - ' . Piwik::translate('Goals_VisitsUntilConv'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'getVisitsUntilConversion',
|
||||
'dimension' => Piwik::translate('Goals_VisitsUntilConv'),
|
||||
'constantRowsCount' => true,
|
||||
'parameters' => array('idGoal' => $goal['idgoal']),
|
||||
'metrics' => $conversionReportMetrics,
|
||||
'order' => 51 + $goal['idgoal'] * 3
|
||||
);
|
||||
|
||||
// Add days to conversion report
|
||||
$reports[] = array(
|
||||
'category' => $goalsCategory,
|
||||
'name' => $goal['name'] . ' - ' . Piwik::translate('Goals_DaysToConv'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'getDaysToConversion',
|
||||
'dimension' => Piwik::translate('Goals_DaysToConv'),
|
||||
'constantRowsCount' => true,
|
||||
'parameters' => array('idGoal' => $goal['idgoal']),
|
||||
'metrics' => $conversionReportMetrics,
|
||||
'order' => 52 + $goal['idgoal'] * 3
|
||||
);
|
||||
}
|
||||
|
||||
$site = new Site($idSite);
|
||||
if ($site->isEcommerceEnabled()) {
|
||||
$category = Piwik::translate('Goals_Ecommerce');
|
||||
$ecommerceMetrics = array_merge($goalMetrics, array(
|
||||
'revenue_subtotal' => Piwik::translate('General_Subtotal'),
|
||||
'revenue_tax' => Piwik::translate('General_Tax'),
|
||||
'revenue_shipping' => Piwik::translate('General_Shipping'),
|
||||
'revenue_discount' => Piwik::translate('General_Discount'),
|
||||
'items' => Piwik::translate('General_PurchasedProducts'),
|
||||
'avg_order_revenue' => Piwik::translate('General_AverageOrderValue')
|
||||
));
|
||||
$ecommerceMetrics['nb_conversions'] = Piwik::translate('General_EcommerceOrders');
|
||||
|
||||
// General Ecommerce metrics
|
||||
$reports[] = array(
|
||||
'category' => $category,
|
||||
'name' => Piwik::translate('General_EcommerceOrders'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'get',
|
||||
'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER),
|
||||
'metrics' => $ecommerceMetrics,
|
||||
'processedMetrics' => false,
|
||||
'order' => 10
|
||||
);
|
||||
$reports[] = array(
|
||||
'category' => $category,
|
||||
'name' => Piwik::translate('General_EcommerceOrders') . ' - ' . Piwik::translate('Goals_VisitsUntilConv'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'getVisitsUntilConversion',
|
||||
'dimension' => Piwik::translate('Goals_VisitsUntilConv'),
|
||||
'constantRowsCount' => true,
|
||||
'metrics' => $conversionReportMetrics,
|
||||
'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER),
|
||||
'order' => 11
|
||||
);
|
||||
$reports[] = array(
|
||||
'category' => $category,
|
||||
'name' => Piwik::translate('General_EcommerceOrders') . ' - ' . Piwik::translate('Goals_DaysToConv'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'getDaysToConversion',
|
||||
'dimension' => Piwik::translate('Goals_DaysToConv'),
|
||||
'constantRowsCount' => true,
|
||||
'metrics' => $conversionReportMetrics,
|
||||
'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER),
|
||||
'order' => 12
|
||||
);
|
||||
|
||||
// Abandoned cart general metrics
|
||||
$abandonedCartMetrics = $goalMetrics;
|
||||
$abandonedCartMetrics['nb_conversions'] = Piwik::translate('General_AbandonedCarts');
|
||||
$abandonedCartMetrics['revenue'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('General_ColumnRevenue'));
|
||||
$abandonedCartMetrics['items'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('Goals_Products'));
|
||||
unset($abandonedCartMetrics['nb_visits_converted']);
|
||||
|
||||
// Abandoned Cart metrics
|
||||
$reports[] = array(
|
||||
'category' => $category,
|
||||
'name' => Piwik::translate('General_AbandonedCarts'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'get',
|
||||
'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART),
|
||||
'metrics' => $abandonedCartMetrics,
|
||||
'processedMetrics' => false,
|
||||
'order' => 15
|
||||
);
|
||||
|
||||
$reports[] = array(
|
||||
'category' => $category,
|
||||
'name' => Piwik::translate('General_AbandonedCarts') . ' - ' . Piwik::translate('Goals_VisitsUntilConv'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'getVisitsUntilConversion',
|
||||
'dimension' => Piwik::translate('Goals_VisitsUntilConv'),
|
||||
'constantRowsCount' => true,
|
||||
'metrics' => $conversionReportMetrics,
|
||||
'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART),
|
||||
'order' => 20
|
||||
);
|
||||
$reports[] = array(
|
||||
'category' => $category,
|
||||
'name' => Piwik::translate('General_AbandonedCarts') . ' - ' . Piwik::translate('Goals_DaysToConv'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'getDaysToConversion',
|
||||
'dimension' => Piwik::translate('Goals_DaysToConv'),
|
||||
'constantRowsCount' => true,
|
||||
'metrics' => $conversionReportMetrics,
|
||||
'parameters' => array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART),
|
||||
'order' => 25
|
||||
);
|
||||
|
||||
// Product reports metadata
|
||||
$productColumns = self::getProductReportColumns();
|
||||
foreach ($this->ecommerceReports as $i => $ecommerceReport) {
|
||||
$reports[] = array(
|
||||
'category' => $category,
|
||||
'name' => Piwik::translate($ecommerceReport[0]),
|
||||
'module' => 'Goals',
|
||||
'action' => $ecommerceReport[2],
|
||||
'dimension' => Piwik::translate($ecommerceReport[0]),
|
||||
'metrics' => $productColumns,
|
||||
'processedMetrics' => false,
|
||||
'order' => 30 + $i
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($goalMetrics['nb_visits_converted']);
|
||||
|
||||
$reportsWithGoals = self::getAllReportsWithGoalMetrics();
|
||||
|
||||
foreach ($reportsWithGoals as $reportWithGoals) {
|
||||
|
|
@ -360,7 +161,7 @@ class Goals extends \Piwik\Plugin
|
|||
foreach ($reports as &$apiReportToUpdate) {
|
||||
if ($apiReportToUpdate['module'] == $reportWithGoals['module']
|
||||
&& $apiReportToUpdate['action'] == $reportWithGoals['action']
|
||||
) {
|
||||
&& empty($apiReportToUpdate['parameters'])) {
|
||||
$apiReportToUpdate['metricsGoal'] = $goalMetrics;
|
||||
$apiReportToUpdate['processedMetricsGoal'] = $goalProcessedMetrics;
|
||||
break;
|
||||
|
|
@ -369,19 +170,30 @@ class Goals extends \Piwik\Plugin
|
|||
}
|
||||
}
|
||||
|
||||
static private function getAllReportsWithGoalMetrics()
|
||||
private static function getAllReportsWithGoalMetrics()
|
||||
{
|
||||
$reportsWithGoals = array();
|
||||
|
||||
foreach (Report::getAllReports() as $report) {
|
||||
if ($report->hasGoalMetrics()) {
|
||||
$reportsWithGoals[] = array(
|
||||
'category' => $report->getCategoryKey(),
|
||||
'name' => $report->getName(),
|
||||
'module' => $report->getModule(),
|
||||
'action' => $report->getAction(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when gathering all reports that contain Goal metrics. The list of reports
|
||||
* will be displayed on the left column of the bottom of every _Goals_ page.
|
||||
*
|
||||
*
|
||||
* If plugins define reports that contain goal metrics (such as **conversions** or **revenue**),
|
||||
* they can use this event to make sure their reports can be viewed on Goals pages.
|
||||
*
|
||||
*
|
||||
* **Example**
|
||||
*
|
||||
*
|
||||
* public function getReportsWithGoalMetrics(&$reports)
|
||||
* {
|
||||
* $reports[] = array(
|
||||
|
|
@ -391,34 +203,23 @@ class Goals extends \Piwik\Plugin
|
|||
* 'action' => 'getMyReport'
|
||||
* );
|
||||
* }
|
||||
*
|
||||
*
|
||||
* @param array &$reportsWithGoals The list of arrays describing reports that have Goal metrics.
|
||||
* Each element of this array must be an array with the following
|
||||
* properties:
|
||||
*
|
||||
*
|
||||
* - **category**: The report category. This should be a translated string.
|
||||
* - **name**: The report's translated name.
|
||||
* - **module**: The plugin the report is in, eg, `'UserCountry'`.
|
||||
* - **action**: The API method of the report, eg, `'getCountry'`.
|
||||
* @ignore
|
||||
* @deprecated since 2.5.0
|
||||
*/
|
||||
Piwik::postEvent('Goals.getReportsWithGoalMetrics', array(&$reportsWithGoals));
|
||||
|
||||
return $reportsWithGoals;
|
||||
}
|
||||
|
||||
static public function getProductReportColumns()
|
||||
{
|
||||
return array(
|
||||
'revenue' => Piwik::translate('General_ProductRevenue'),
|
||||
'quantity' => Piwik::translate('General_Quantity'),
|
||||
'orders' => Piwik::translate('General_UniquePurchases'),
|
||||
'avg_price' => Piwik::translate('General_AveragePrice'),
|
||||
'avg_quantity' => Piwik::translate('General_AverageQuantity'),
|
||||
'nb_visits' => Piwik::translate('General_ColumnNbVisits'),
|
||||
'conversion_rate' => Piwik::translate('General_ProductConversionRate'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function executes when the 'Goals.getReportsWithGoalMetrics' event fires. It
|
||||
* adds the 'visits to conversion' report metadata to the list of goal reports so
|
||||
|
|
@ -427,13 +228,13 @@ class Goals extends \Piwik\Plugin
|
|||
public function getActualReportsWithGoalMetrics(&$dimensions)
|
||||
{
|
||||
$reportWithGoalMetrics = array(
|
||||
array('category' => Piwik::translate('General_Visit'),
|
||||
array('category' => 'General_Visit',
|
||||
'name' => Piwik::translate('Goals_VisitsUntilConv'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'getVisitsUntilConversion',
|
||||
'viewDataTable' => 'table',
|
||||
),
|
||||
array('category' => Piwik::translate('General_Visit'),
|
||||
array('category' => 'General_Visit',
|
||||
'name' => Piwik::translate('Goals_DaysToConv'),
|
||||
'module' => 'Goals',
|
||||
'action' => 'getDaysToConversion',
|
||||
|
|
@ -443,18 +244,6 @@ class Goals extends \Piwik\Plugin
|
|||
$dimensions = array_merge($dimensions, $reportWithGoalMetrics);
|
||||
}
|
||||
|
||||
public function getSegmentsMetadata(&$segments)
|
||||
{
|
||||
$segments[] = array(
|
||||
'type' => 'dimension',
|
||||
'category' => Piwik::translate('General_Visit'),
|
||||
'name' => 'General_VisitConvertedGoalId',
|
||||
'segment' => 'visitConvertedGoalId',
|
||||
'sqlSegment' => 'log_conversion.idgoal',
|
||||
'acceptedValues' => '1, 2, 3, etc.',
|
||||
);
|
||||
}
|
||||
|
||||
public function getJsFiles(&$jsFiles)
|
||||
{
|
||||
$jsFiles[] = "plugins/Goals/javascripts/goalsForm.js";
|
||||
|
|
@ -471,210 +260,14 @@ class Goals extends \Piwik\Plugin
|
|||
$array['goals'] = API::getInstance()->getGoals($idSite);
|
||||
}
|
||||
|
||||
public function addWidgets()
|
||||
{
|
||||
$idSite = Common::getRequestVar('idSite', null, 'int');
|
||||
|
||||
// Ecommerce widgets
|
||||
$site = new Site($idSite);
|
||||
if ($site->isEcommerceEnabled()) {
|
||||
WidgetsList::add('Goals_Ecommerce', 'Goals_EcommerceOverview', 'Goals', 'widgetGoalReport', array('idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER));
|
||||
WidgetsList::add('Goals_Ecommerce', 'Goals_EcommerceLog', 'Goals', 'getEcommerceLog');
|
||||
foreach ($this->ecommerceReports as $widget) {
|
||||
WidgetsList::add('Goals_Ecommerce', $widget[0], $widget[1], $widget[2]);
|
||||
}
|
||||
}
|
||||
|
||||
// Goals widgets
|
||||
WidgetsList::add('Goals_Goals', 'Goals_GoalsOverview', 'Goals', 'widgetGoalsOverview');
|
||||
$goals = API::getInstance()->getGoals($idSite);
|
||||
if (count($goals) > 0) {
|
||||
foreach ($goals as $goal) {
|
||||
WidgetsList::add('Goals_Goals', Common::sanitizeInputValue($goal['name']), 'Goals', 'widgetGoalReport', array('idGoal' => $goal['idgoal']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addMenus()
|
||||
{
|
||||
$idSite = Common::getRequestVar('idSite', null, 'int');
|
||||
$goals = API::getInstance()->getGoals($idSite);
|
||||
$mainGoalMenu = $this->getGoalCategoryName($idSite);
|
||||
$site = new Site($idSite);
|
||||
if (count($goals) == 0) {
|
||||
MenuMain::getInstance()->add($mainGoalMenu, '', array(
|
||||
'module' => 'Goals',
|
||||
'action' => ($site->isEcommerceEnabled() ? 'ecommerceReport' : 'addNewGoal'),
|
||||
'idGoal' => ($site->isEcommerceEnabled() ? Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER : null)),
|
||||
true,
|
||||
25);
|
||||
if ($site->isEcommerceEnabled()) {
|
||||
MenuMain::getInstance()->add($mainGoalMenu, 'Goals_Ecommerce', array('module' => 'Goals', 'action' => 'ecommerceReport', 'idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER), true, 1);
|
||||
}
|
||||
MenuMain::getInstance()->add($mainGoalMenu, 'Goals_AddNewGoal', array('module' => 'Goals', 'action' => 'addNewGoal'));
|
||||
} else {
|
||||
MenuMain::getInstance()->add($mainGoalMenu, '', array(
|
||||
'module' => 'Goals',
|
||||
'action' => ($site->isEcommerceEnabled() ? 'ecommerceReport' : 'index'),
|
||||
'idGoal' => ($site->isEcommerceEnabled() ? Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER : null)),
|
||||
true,
|
||||
25);
|
||||
|
||||
if ($site->isEcommerceEnabled()) {
|
||||
MenuMain::getInstance()->add($mainGoalMenu, 'Goals_Ecommerce', array('module' => 'Goals', 'action' => 'ecommerceReport', 'idGoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER), true, 1);
|
||||
}
|
||||
MenuMain::getInstance()->add($mainGoalMenu, 'Goals_GoalsOverview', array('module' => 'Goals', 'action' => 'index'), true, 2);
|
||||
foreach ($goals as $goal) {
|
||||
MenuMain::getInstance()->add($mainGoalMenu, str_replace('%', '%%', Translate::clean($goal['name'])), array('module' => 'Goals', 'action' => 'goalReport', 'idGoal' => $goal['idgoal']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getGoalCategoryName($idSite)
|
||||
{
|
||||
$site = new Site($idSite);
|
||||
return $site->isEcommerceEnabled() ? 'Goals_EcommerceAndGoalsMenu' : 'Goals_Goals';
|
||||
}
|
||||
|
||||
public function configureViewDataTable(ViewDataTable $view)
|
||||
{
|
||||
switch ($view->requestConfig->apiMethodToRequestDataTable) {
|
||||
case 'Goals.getItemsSku':
|
||||
$this->configureViewForGetItemsSku($view);
|
||||
break;
|
||||
case 'Goals.getItemsName':
|
||||
$this->configureViewForGetItemsName($view);
|
||||
break;
|
||||
case 'Goals.getItemsCategory':
|
||||
$this->configureViewForGetItemsCategory($view);
|
||||
break;
|
||||
case 'Goals.getVisitsUntilConversion':
|
||||
$this->configureViewForGetVisitsUntilConversion($view);
|
||||
break;
|
||||
case 'Goals.getDaysToConversion':
|
||||
$this->configureViewForGetDaysToConversion($view);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function configureViewForGetItemsSku(ViewDataTable $view)
|
||||
{
|
||||
return $this->configureViewForItemsReport($view, Piwik::translate('Goals_ProductSKU'));
|
||||
}
|
||||
|
||||
private function configureViewForGetItemsName(ViewDataTable $view)
|
||||
{
|
||||
return $this->configureViewForItemsReport($view, Piwik::translate('Goals_ProductName'));
|
||||
}
|
||||
|
||||
private function configureViewForGetItemsCategory(ViewDataTable $view)
|
||||
{
|
||||
return $this->configureViewForItemsReport($view, Piwik::translate('Goals_ProductCategory'));
|
||||
}
|
||||
|
||||
private function configureViewForGetVisitsUntilConversion(ViewDataTable $view)
|
||||
{
|
||||
$view->config->show_search = false;
|
||||
$view->config->show_exclude_low_population = false;
|
||||
$view->config->show_table_all_columns = false;
|
||||
$view->config->columns_to_display = array('label', 'nb_conversions');
|
||||
$view->config->show_offset_information = false;
|
||||
$view->config->show_pagination_control = false;
|
||||
$view->config->show_all_views_icons = false;
|
||||
|
||||
$view->requestConfig->filter_sort_column = 'label';
|
||||
$view->requestConfig->filter_sort_order = 'asc';
|
||||
$view->requestConfig->filter_limit = count(Archiver::$visitCountRanges);
|
||||
|
||||
$view->config->addTranslations(array(
|
||||
'label' => Piwik::translate('Goals_VisitsUntilConv'),
|
||||
'nb_conversions' => Piwik::translate('Goals_ColumnConversions'),
|
||||
));
|
||||
}
|
||||
|
||||
private function configureViewForGetDaysToConversion(ViewDataTable $view)
|
||||
{
|
||||
$view->config->show_search = false;
|
||||
$view->config->show_exclude_low_population = false;
|
||||
$view->config->show_table_all_columns = false;
|
||||
$view->config->show_all_views_icons = false;
|
||||
$view->config->show_offset_information = false;
|
||||
$view->config->show_pagination_control = false;
|
||||
$view->config->columns_to_display = array('label', 'nb_conversions');
|
||||
|
||||
$view->requestConfig->filter_sort_column = 'label';
|
||||
$view->requestConfig->filter_sort_order = 'asc';
|
||||
$view->requestConfig->filter_limit = count(Archiver::$daysToConvRanges);
|
||||
|
||||
$view->config->addTranslations(array(
|
||||
'label' => Piwik::translate('Goals_DaysToConv'),
|
||||
'nb_conversions' => Piwik::translate('Goals_ColumnConversions'),
|
||||
));
|
||||
}
|
||||
|
||||
private function configureViewForItemsReport(ViewDataTable $view, $label)
|
||||
{
|
||||
$idSite = Common::getRequestVar('idSite');
|
||||
|
||||
$moneyColumns = array('revenue', 'avg_price');
|
||||
$prettifyMoneyColumns = array(
|
||||
'ColumnCallbackReplace', array($moneyColumns, '\Piwik\MetricsFormatter::getPrettyMoney', array($idSite)));
|
||||
|
||||
$view->config->show_ecommerce = true;
|
||||
$view->config->show_table = false;
|
||||
$view->config->show_all_views_icons = false;
|
||||
$view->config->show_exclude_low_population = false;
|
||||
$view->config->show_table_all_columns = false;
|
||||
$view->config->addTranslation('label', $label);
|
||||
$view->config->filters[] = $prettifyMoneyColumns;
|
||||
|
||||
$view->requestConfig->filter_limit = 10;
|
||||
$view->requestConfig->filter_sort_column = 'revenue';
|
||||
$view->requestConfig->filter_sort_order = 'desc';
|
||||
|
||||
// set columns/translations which differ based on viewDataTable TODO: shouldn't have to do this check... amount of reports should be dynamic, but metadata should be static
|
||||
$columns = Goals::getProductReportColumns();
|
||||
|
||||
$abandonedCart = Common::getRequestVar('viewDataTable', 'ecommerceOrder', 'string') == 'ecommerceAbandonedCart';
|
||||
if ($abandonedCart) {
|
||||
$columns['abandoned_carts'] = Piwik::translate('General_AbandonedCarts');
|
||||
$columns['revenue'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('General_ProductRevenue'));
|
||||
$columns['quantity'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('General_Quantity'));
|
||||
$columns['avg_quantity'] = Piwik::translate('Goals_LeftInCart', Piwik::translate('General_AverageQuantity'));
|
||||
unset($columns['orders']);
|
||||
unset($columns['conversion_rate']);
|
||||
|
||||
$view->requestConfig->request_parameters_to_modify['abandonedCarts'] = '1';
|
||||
}
|
||||
|
||||
$translations = array_merge(array('label' => $label), $columns);
|
||||
|
||||
$view->config->addTranslations($translations);
|
||||
$view->config->columns_to_display = array_keys($translations);
|
||||
|
||||
// set metrics documentation in normal ecommerce report
|
||||
if (!$abandonedCart) {
|
||||
$view->config->metrics_documentation = array(
|
||||
'revenue' => Piwik::translate('Goals_ColumnRevenueDocumentation',
|
||||
Piwik::translate('Goals_DocumentationRevenueGeneratedByProductSales')),
|
||||
'quantity' => Piwik::translate('Goals_ColumnQuantityDocumentation', $label),
|
||||
'orders' => Piwik::translate('Goals_ColumnOrdersDocumentation', $label),
|
||||
'avg_price' => Piwik::translate('Goals_ColumnAveragePriceDocumentation', $label),
|
||||
'avg_quantity' => Piwik::translate('Goals_ColumnAverageQuantityDocumentation', $label),
|
||||
'nb_visits' => Piwik::translate('Goals_ColumnVisitsProductDocumentation', $label),
|
||||
'conversion_rate' => Piwik::translate('Goals_ColumnConversionRateProductDocumentation', $label),
|
||||
);
|
||||
}
|
||||
|
||||
$view->config->custom_parameters['viewDataTable'] =
|
||||
$abandonedCart ? Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART : Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER;
|
||||
}
|
||||
|
||||
|
||||
public function getClientSideTranslationKeys(&$translationKeys)
|
||||
{
|
||||
$translationKeys[] = 'Goals_AddGoal';
|
||||
$translationKeys[] = 'Goals_UpdateGoal';
|
||||
$translationKeys[] = 'Goals_DeleteGoalConfirm';
|
||||
$translationKeys[] = 'Goals_UpdateGoal';
|
||||
$translationKeys[] = 'Goals_DeleteGoalConfirm';
|
||||
$translationKeys[] = 'Goals_Ecommerce';
|
||||
$translationKeys[] = 'Goals_Optional';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue