merge
This commit is contained in:
commit
046a724272
4209 changed files with 1186656 additions and 0 deletions
567
www/analytics/plugins/Goals/API.php
Normal file
567
www/analytics/plugins/Goals/API.php
Normal file
|
|
@ -0,0 +1,567 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\Goals;
|
||||
|
||||
use Exception;
|
||||
use Piwik\Archive;
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Db;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Site;
|
||||
use Piwik\Tracker\Cache;
|
||||
use Piwik\Tracker\GoalManager;
|
||||
|
||||
/**
|
||||
* Goals API lets you Manage existing goals, via "updateGoal" and "deleteGoal", create new Goals via "addGoal",
|
||||
* or list existing Goals for one or several websites via "getGoals"
|
||||
*
|
||||
* If you are <a href='http://piwik.org/docs/ecommerce-analytics/' target='_blank'>tracking Ecommerce orders and products</a> on your site, the functions "getItemsSku", "getItemsName" and "getItemsCategory"
|
||||
* will return the list of products purchased on your site, either grouped by Product SKU, Product Name or Product Category. For each name, SKU or category, the following
|
||||
* metrics are returned: Total revenue, Total quantity, average price, average quantity, number of orders (or abandoned carts) containing this product, number of visits on the Product page,
|
||||
* Conversion rate.
|
||||
*
|
||||
* By default, these functions return the 'Products purchased'. These functions also accept an optional parameter &abandonedCarts=1.
|
||||
* If the parameter is set, it will instead return the metrics for products that were left in an abandoned cart therefore not purchased.
|
||||
*
|
||||
* The API also lets you request overall Goal metrics via the method "get": Conversions, Visits with at least one conversion, Conversion rate and Revenue.
|
||||
* 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.
|
||||
*
|
||||
* @method static \Piwik\Plugins\Goals\API getInstance()
|
||||
*/
|
||||
class API extends \Piwik\Plugin\API
|
||||
{
|
||||
const AVG_PRICE_VIEWED = 'avg_price_viewed';
|
||||
|
||||
/**
|
||||
* Returns all Goals for a given website, or list of websites
|
||||
*
|
||||
* @param string|array $idSite Array or Comma separated list of website IDs to request the goals for
|
||||
* @return array Array of Goal attributes
|
||||
*/
|
||||
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']);
|
||||
}
|
||||
$cleanedGoals[$goal['idgoal']] = $goal;
|
||||
}
|
||||
return $cleanedGoals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Goal for a given website.
|
||||
*
|
||||
* @param int $idSite
|
||||
* @param string $name
|
||||
* @param string $matchAttribute 'url', 'title', 'file', 'external_website' or 'manually'
|
||||
* @param string $pattern eg. purchase-confirmation.htm
|
||||
* @param string $patternType 'regex', 'contains', 'exact'
|
||||
* @param bool $caseSensitive
|
||||
* @param bool|float $revenue If set, default revenue to assign to conversions
|
||||
* @param bool $allowMultipleConversionsPerVisit By default, multiple conversions in the same visit will only record the first conversion.
|
||||
* If set to true, multiple conversions will all be recorded within a visit (useful for Ecommerce goals)
|
||||
* @return int ID of the new goal
|
||||
*/
|
||||
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);
|
||||
$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,
|
||||
));
|
||||
Cache::regenerateCacheWebsiteAttributes($idSite);
|
||||
return $idGoal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a Goal description.
|
||||
* Will not update or re-process the conversions already recorded
|
||||
*
|
||||
* @see addGoal() for parameters description
|
||||
* @param int $idSite
|
||||
* @param int $idGoal
|
||||
* @param $name
|
||||
* @param $matchAttribute
|
||||
* @param string $pattern
|
||||
* @param string $patternType
|
||||
* @param bool $caseSensitive
|
||||
* @param bool|float $revenue
|
||||
* @param bool $allowMultipleConversionsPerVisit
|
||||
* @return void
|
||||
*/
|
||||
public function updateGoal($idSite, $idGoal, $name, $matchAttribute, $pattern, $patternType, $caseSensitive = false, $revenue = false, $allowMultipleConversionsPerVisit = false)
|
||||
{
|
||||
Piwik::checkUserHasAdminAccess($idSite);
|
||||
$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'"
|
||||
);
|
||||
Cache::regenerateCacheWebsiteAttributes($idSite);
|
||||
}
|
||||
|
||||
private function checkPatternIsValid($patternType, $pattern)
|
||||
{
|
||||
if ($patternType == 'exact'
|
||||
&& substr($pattern, 0, 4) != 'http'
|
||||
) {
|
||||
throw new Exception(Piwik::translate('Goals_ExceptionInvalidMatchingString', array("http:// or https://", "http://www.yourwebsite.com/newsletter/subscribed.html")));
|
||||
}
|
||||
}
|
||||
|
||||
private function checkName($name)
|
||||
{
|
||||
return urldecode($name);
|
||||
}
|
||||
|
||||
private function checkPattern($pattern)
|
||||
{
|
||||
return urldecode($pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Soft deletes a given Goal.
|
||||
* Stats data in the archives will still be recorded, but not displayed.
|
||||
*
|
||||
* @param int $idSite
|
||||
* @param int $idGoal
|
||||
* @return void
|
||||
*/
|
||||
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));
|
||||
Cache::regenerateCacheWebsiteAttributes($idSite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a datatable of Items SKU/name or categories and their metrics
|
||||
* If $abandonedCarts set to 1, will return items abandoned in carts. If set to 0, will return items ordered
|
||||
*/
|
||||
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));
|
||||
|
||||
$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->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;
|
||||
}
|
||||
|
||||
protected function renameNotDefinedRow($dataTable, $notDefinedStringPretty)
|
||||
{
|
||||
if ($dataTable instanceof DataTable\Map) {
|
||||
foreach ($dataTable->getDataTables() as $table) {
|
||||
$this->renameNotDefinedRow($table, $notDefinedStringPretty);
|
||||
}
|
||||
return;
|
||||
}
|
||||
$rowNotDefined = $dataTable->getRowFromLabel(\Piwik\Plugins\CustomVariables\Archiver::LABEL_CUSTOM_VALUE_NOT_DEFINED);
|
||||
if ($rowNotDefined) {
|
||||
$rowNotDefined->setColumn('label', $notDefinedStringPretty);
|
||||
}
|
||||
}
|
||||
|
||||
protected function enrichItemsDataTableWithItemsViewMetrics($dataTable, $idSite, $period, $date, $segment, $idSubtable)
|
||||
{
|
||||
$ecommerceViews = \Piwik\Plugins\CustomVariables\API::getInstance()->getCustomVariablesValuesFromNameId($idSite, $period, $date, $idSubtable, $segment, $_leavePriceViewedColumn = true);
|
||||
|
||||
// For Product names and SKU reports, and for Category report
|
||||
// Use the Price (tracked on page views)
|
||||
// ONLY when the price sold in conversions is not found (ie. product viewed but not sold)
|
||||
foreach ($ecommerceViews->getRows() as $rowView) {
|
||||
// If there is not already a 'sum price' for this product
|
||||
$rowFound = $dataTable->getRowFromLabel($rowView->getColumn('label'));
|
||||
$price = $rowFound
|
||||
? $rowFound->getColumn(Metrics::INDEX_ECOMMERCE_ITEM_PRICE)
|
||||
: false;
|
||||
if (empty($price)) {
|
||||
// If a price was tracked on the product page
|
||||
if ($rowView->getColumn(Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED)) {
|
||||
$rowView->renameColumn(Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED, self::AVG_PRICE_VIEWED);
|
||||
}
|
||||
}
|
||||
$rowView->deleteColumn(Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED);
|
||||
}
|
||||
|
||||
$dataTable->addDataTable($ecommerceViews);
|
||||
}
|
||||
|
||||
public function getItemsSku($idSite, $period, $date, $abandonedCarts = false, $segment = false)
|
||||
{
|
||||
return $this->getItems('Goals_ItemsSku', $idSite, $period, $date, $abandonedCarts, $segment);
|
||||
}
|
||||
|
||||
public function getItemsName($idSite, $period, $date, $abandonedCarts = false, $segment = false)
|
||||
{
|
||||
return $this->getItems('Goals_ItemsName', $idSite, $period, $date, $abandonedCarts, $segment);
|
||||
}
|
||||
|
||||
public function getItemsCategory($idSite, $period, $date, $abandonedCarts = false, $segment = false)
|
||||
{
|
||||
return $this->getItems('Goals_ItemsCategory', $idSite, $period, $date, $abandonedCarts, $segment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that checks for special string goal IDs and converts them to
|
||||
* their integer equivalents.
|
||||
*
|
||||
* Checks for the following values:
|
||||
* Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER
|
||||
* Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART
|
||||
*
|
||||
* @param string|int $idGoal The goal id as an integer or a special string.
|
||||
* @return int The numeric goal id.
|
||||
*/
|
||||
protected static function convertSpecialGoalIds($idGoal)
|
||||
{
|
||||
if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
|
||||
return GoalManager::IDGOAL_ORDER;
|
||||
} else if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART) {
|
||||
return GoalManager::IDGOAL_CART;
|
||||
} else {
|
||||
return $idGoal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Goals data
|
||||
*
|
||||
* @param int $idSite
|
||||
* @param string $period
|
||||
* @param string $date
|
||||
* @param bool $segment
|
||||
* @param bool|int $idGoal
|
||||
* @param array $columns Array of metrics to fetch: nb_conversions, conversion_rate, revenue
|
||||
* @return DataTable
|
||||
*/
|
||||
public function get($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);
|
||||
|
||||
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);
|
||||
|
||||
// Rewrite column names as we expect them
|
||||
foreach ($columnsToSelect as $id => $oldName) {
|
||||
$dataTable->renameColumn($oldName, $columns[$id]);
|
||||
}
|
||||
if ($idGoal == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) {
|
||||
if ($dataTable instanceof DataTable\Map) {
|
||||
foreach ($dataTable->getDataTables() as $row) {
|
||||
$this->enrichTable($row);
|
||||
}
|
||||
} else {
|
||||
$this->enrichTable($dataTable);
|
||||
}
|
||||
}
|
||||
return $dataTable;
|
||||
}
|
||||
|
||||
protected function enrichTable($table)
|
||||
{
|
||||
$row = $table->getFirstRow();
|
||||
if (!$row) {
|
||||
return;
|
||||
}
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getNumeric($idSite, $period, $date, $segment, $toFetch)
|
||||
{
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
$archive = Archive::build($idSite, $period, $date, $segment);
|
||||
$dataTable = $archive->getDataTableFromNumeric($toFetch);
|
||||
return $dataTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
public function getConversions($idSite, $period, $date, $segment = false, $idGoal = false)
|
||||
{
|
||||
return $this->getNumeric($idSite, $period, $date, $segment, Archiver::getRecordName('nb_conversions', $idGoal));
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
public function getNbVisitsConverted($idSite, $period, $date, $segment = false, $idGoal = false)
|
||||
{
|
||||
return $this->getNumeric($idSite, $period, $date, $segment, Archiver::getRecordName('nb_visits_converted', $idGoal));
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
public function getConversionRate($idSite, $period, $date, $segment = false, $idGoal = false)
|
||||
{
|
||||
return $this->getNumeric($idSite, $period, $date, $segment, Archiver::getRecordName('conversion_rate', $idGoal));
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
public function getRevenue($idSite, $period, $date, $segment = false, $idGoal = false)
|
||||
{
|
||||
return $this->getNumeric($idSite, $period, $date, $segment, Archiver::getRecordName('revenue', $idGoal));
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that retrieve an archived DataTable for a specific site, date range,
|
||||
* segment and goal. If not goal is specified, this method will retrieve and sum the
|
||||
* data for every goal.
|
||||
*
|
||||
* @param string $recordName The archive entry name.
|
||||
* @param int|string $idSite The site(s) to select data for.
|
||||
* @param string $period The period type.
|
||||
* @param string $date The date type.
|
||||
* @param string $segment The segment.
|
||||
* @param int|bool $idGoal The id of the goal to get data for. If this is set to false,
|
||||
* data for every goal that belongs to $idSite is returned.
|
||||
* @return false|DataTable
|
||||
*/
|
||||
protected function getGoalSpecificDataTable($recordName, $idSite, $period, $date, $segment, $idGoal)
|
||||
{
|
||||
Piwik::checkUserHasViewAccess($idSite);
|
||||
|
||||
$archive = Archive::build($idSite, $period, $date, $segment);
|
||||
|
||||
// check for the special goal ids
|
||||
$realGoalId = $idGoal != true ? false : self::convertSpecialGoalIds($idGoal);
|
||||
|
||||
// get the data table
|
||||
$dataTable = $archive->getDataTable(Archiver::getRecordName($recordName, $realGoalId), $idSubtable = null);
|
||||
$dataTable->queueFilter('ReplaceColumnNames');
|
||||
|
||||
return $dataTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a DataTable that maps ranges of days to the number of conversions that occurred
|
||||
* within those ranges, for the specified site, date range, segment and goal.
|
||||
*
|
||||
* @param int $idSite The site to select data from.
|
||||
* @param string $period The period type.
|
||||
* @param string $date The date type.
|
||||
* @param string|bool $segment The segment.
|
||||
* @param int|bool $idGoal The id of the goal to get data for. If this is set to false,
|
||||
* data for every goal that belongs to $idSite is returned.
|
||||
* @return false|DataTable
|
||||
*/
|
||||
public function getDaysToConversion($idSite, $period, $date, $segment = false, $idGoal = false)
|
||||
{
|
||||
$dataTable = $this->getGoalSpecificDataTable(
|
||||
Archiver::DAYS_UNTIL_CONV_RECORD_NAME, $idSite, $period, $date, $segment, $idGoal);
|
||||
|
||||
$dataTable->queueFilter('Sort', array('label', 'asc', true));
|
||||
$dataTable->queueFilter(
|
||||
'BeautifyRangeLabels', array(Piwik::translate('General_OneDay'), Piwik::translate('General_NDays')));
|
||||
|
||||
return $dataTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a DataTable that maps ranges of visit counts to the number of conversions that
|
||||
* occurred on those visits for the specified site, date range, segment and goal.
|
||||
*
|
||||
* @param int $idSite The site to select data from.
|
||||
* @param string $period The period type.
|
||||
* @param string $date The date type.
|
||||
* @param string|bool $segment The segment.
|
||||
* @param int|bool $idGoal The id of the goal to get data for. If this is set to false,
|
||||
* data for every goal that belongs to $idSite is returned.
|
||||
* @return bool|DataTable
|
||||
*/
|
||||
public function getVisitsUntilConversion($idSite, $period, $date, $segment = false, $idGoal = false)
|
||||
{
|
||||
$dataTable = $this->getGoalSpecificDataTable(
|
||||
Archiver::VISITS_UNTIL_RECORD_NAME, $idSite, $period, $date, $segment, $idGoal);
|
||||
|
||||
$dataTable->queueFilter('Sort', array('label', 'asc', true));
|
||||
$dataTable->queueFilter(
|
||||
'BeautifyRangeLabels', array(Piwik::translate('General_OneVisit'), Piwik::translate('General_NVisits')));
|
||||
|
||||
return $dataTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhances the dataTable with Items attributes found in the Custom Variables report.
|
||||
*
|
||||
* @param $dataTable
|
||||
* @param $recordName
|
||||
* @param $idSite
|
||||
* @param $period
|
||||
* @param $date
|
||||
* @param $segment
|
||||
*/
|
||||
protected function enrichItemsTableWithViewMetrics($dataTable, $recordName, $idSite, $period, $date, $segment)
|
||||
{
|
||||
// Enrich the datatable with Product/Categories views, and conversion rates
|
||||
$customVariables = \Piwik\Plugins\CustomVariables\API::getInstance()->getCustomVariables($idSite, $period, $date, $segment, $expanded = false,
|
||||
$_leavePiwikCoreVariables = true);
|
||||
$mapping = array(
|
||||
'Goals_ItemsSku' => '_pks',
|
||||
'Goals_ItemsName' => '_pkn',
|
||||
'Goals_ItemsCategory' => '_pkc',
|
||||
);
|
||||
$reportToNotDefinedString = array(
|
||||
'Goals_ItemsSku' => Piwik::translate('General_NotDefined', Piwik::translate('Goals_ProductSKU')), // Note: this should never happen
|
||||
'Goals_ItemsName' => Piwik::translate('General_NotDefined', Piwik::translate('Goals_ProductName')),
|
||||
'Goals_ItemsCategory' => Piwik::translate('General_NotDefined', Piwik::translate('Goals_ProductCategory'))
|
||||
);
|
||||
$notDefinedStringPretty = $reportToNotDefinedString[$recordName];
|
||||
$customVarNameToLookFor = $mapping[$recordName];
|
||||
|
||||
// Handle case where date=last30&period=day
|
||||
if ($customVariables instanceof DataTable\Map) {
|
||||
$customVariableDatatables = $customVariables->getDataTables();
|
||||
$dataTables = $dataTable->getDataTables();
|
||||
foreach ($customVariableDatatables as $key => $customVariableTableForDate) {
|
||||
$dataTableForDate = isset($dataTables[$key]) ? $dataTables[$key] : new DataTable();
|
||||
|
||||
// we do not enter the IF
|
||||
// if case idSite=1,3 AND period=day&date=datefrom,dateto,
|
||||
if ($customVariableTableForDate instanceof DataTable
|
||||
&& $customVariableTableForDate->getMetadata(Archive\DataTableFactory::TABLE_METADATA_PERIOD_INDEX)
|
||||
) {
|
||||
$dateRewrite = $customVariableTableForDate->getMetadata(Archive\DataTableFactory::TABLE_METADATA_PERIOD_INDEX)->getDateStart()->toString();
|
||||
$row = $customVariableTableForDate->getRowFromLabel($customVarNameToLookFor);
|
||||
if ($row) {
|
||||
$idSubtable = $row->getIdSubDataTable();
|
||||
$this->enrichItemsDataTableWithItemsViewMetrics($dataTableForDate, $idSite, $period, $dateRewrite, $segment, $idSubtable);
|
||||
}
|
||||
$dataTable->addTable($dataTableForDate, $key);
|
||||
}
|
||||
$this->renameNotDefinedRow($dataTableForDate, $notDefinedStringPretty);
|
||||
}
|
||||
} elseif ($customVariables instanceof DataTable) {
|
||||
$row = $customVariables->getRowFromLabel($customVarNameToLookFor);
|
||||
if ($row) {
|
||||
$idSubtable = $row->getIdSubDataTable();
|
||||
$this->enrichItemsDataTableWithItemsViewMetrics($dataTable, $idSite, $period, $date, $segment, $idSubtable);
|
||||
}
|
||||
$this->renameNotDefinedRow($dataTable, $notDefinedStringPretty);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue