private function addEcommerceWidgets(WidgetsList $widgetsList) { $goals = new Goals(); $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 ($goals->getEcommerceReports() as $widget) { $widgetsList->add('Goals_Ecommerce', $widget[0], $widget[1], $widget[2]); } }
public function configureWidgets(WidgetsList $widgetsList, ReportWidgetFactory $factory) { $idSite = Common::getRequestVar('idSite', 0, 'int'); if (empty($idSite)) { return; } $goals = $this->getGoals(); $reports = Goals::getReportsWithGoalMetrics(); $page = new Pages($factory, $reports); $widgetsList->addWidgetConfigs($page->createGoalsOverviewPage($goals)); if ($this->isEcommerceEnabled($idSite)) { $widgetsList->addWidgetConfigs($page->createEcommerceOverviewPage()); $widgetsList->addWidgetConfigs($page->createEcommerceSalesPage()); } foreach ($goals as $goal) { $widgetsList->addWidgetConfigs($page->createGoalDetailPage($goal)); } }
/** * @internal param $this->getProcessor() */ public function aggregateMultipleReports() { /* * Archive Ecommerce Items */ $dataTableToSum = $this->dimensionRecord; foreach ($this->dimensionRecord as $recordName) { $dataTableToSum[] = self::getItemRecordNameAbandonedCart($recordName); } $this->getProcessor()->aggregateDataTableRecords($dataTableToSum); /* * Archive General Goal metrics */ $goalIdsToSum = GoalManager::getGoalIds($this->getProcessor()->getParams()->getSite()->getId()); //Ecommerce $goalIdsToSum[] = GoalManager::IDGOAL_ORDER; $goalIdsToSum[] = GoalManager::IDGOAL_CART; //bug here if idgoal=1 // Overall goal metrics $goalIdsToSum[] = false; $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); // 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))); } // sum up goal overview reports $this->getProcessor()->aggregateDataTableRecords(array(self::getRecordName(self::VISITS_UNTIL_RECORD_NAME), self::getRecordName(self::DAYS_UNTIL_CONV_RECORD_NAME))); }
/** * Utility function that returns HTML that displays Goal information for reports. This * is the HTML that is at the bottom of every goals page. * * @param int $conversions The number of conversions for this goal (or all goals * in case of the overview). * @param bool $ecommerce Whether to show ecommerce reports or not. * @param bool $cartNbConversions Whether there are cart conversions or not for this * goal. * @return string */ private function getGoalReportsByDimensionTable($conversions, $ecommerce = false, $cartNbConversions = false) { $preloadAbandonedCart = $cartNbConversions !== false && $conversions == 0; $goalReportsByDimension = new ReportsByDimension('Goals'); // add ecommerce reports $ecommerceCustomParams = array(); if ($ecommerce) { if ($preloadAbandonedCart) { $ecommerceCustomParams['viewDataTable'] = 'ecommerceAbandonedCart'; $ecommerceCustomParams['filterEcommerce'] = self::ECOMMERCE_LOG_SHOW_ABANDONED_CARTS; } $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) { // for non-Goals reports, we show the goals table $customParams = $ecommerceCustomParams + array('documentationForGoalsPage' => '1'); if (Common::getRequestVar('idGoal', '') === '') { $customParams['idGoal'] = '0'; // NOTE: Must be string! Otherwise Piwik_View_HtmlTable_Goals fails. } $allReports = Goals::getReportsWithGoalMetrics(); foreach ($allReports as $category => $reports) { $categoryText = Piwik::translate('Goals_ViewGoalsBy', $category); foreach ($reports as $report) { $customParams['viewDataTable'] = 'tableGoals'; if (in_array($report['action'], array('getVisitsUntilConversion', 'getDaysToConversion'))) { $customParams['viewDataTable'] = 'table'; } $goalReportsByDimension->addReport($categoryText, $report['name'], $report['module'] . '.' . $report['action'], $customParams); } } } return $goalReportsByDimension->render(); }
/** * Utility function that returns HTML that displays Goal information for reports. This * is the HTML that is at the bottom of every goals page. * * @param int $conversions The number of conversions for this goal (or all goals * in case of the overview). * @param bool $ecommerce Whether to show ecommerce reports or not. * @param bool $cartNbConversions Whether there are cart conversions or not for this * goal. * @return string */ private function getGoalReportsByDimensionTable($conversions, $ecommerce = false, $cartNbConversions = false) { $preloadAbandonedCart = $cartNbConversions !== false && $conversions == 0; $goalReportsByDimension = new ReportsByDimension('Goals'); // add ecommerce reports $ecommerceCustomParams = array(); if ($ecommerce) { if ($preloadAbandonedCart) { $ecommerceCustomParams['abandonedCarts'] = '1'; } else { $ecommerceCustomParams['abandonedCarts'] = '0'; } } if ($conversions > 0 || $ecommerce) { // for non-Goals reports, we show the goals table $customParams = $ecommerceCustomParams + array('documentationForGoalsPage' => '1'); if (Common::getRequestVar('idGoal', '') === '') { $customParams['idGoal'] = '0'; // NOTE: Must be string! Otherwise Piwik_View_HtmlTable_Goals fails. } $allReports = Goals::getReportsWithGoalMetrics(); foreach ($allReports as $category => $reports) { if ($ecommerce) { $categoryText = $this->translationHelper->translateEcommerceMetricCategory($category); } else { $categoryText = $this->translationHelper->translateGoalMetricCategory($category); } foreach ($reports as $report) { if (empty($report['viewDataTable']) && empty($report['abandonedCarts'])) { $report['viewDataTable'] = 'tableGoals'; } $customParams['viewDataTable'] = $report['viewDataTable']; $goalReportsByDimension->addReport($categoryText, $report['name'], $report['module'] . '.' . $report['action'], $customParams); } } } return $goalReportsByDimension->render(); }
/** * 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; }
/** * 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); // Mapping string idGoal to internal ID $idGoal = self::convertSpecialGoalIds($idGoal); $isEcommerceGoal = $idGoal === GoalManager::IDGOAL_ORDER || $idGoal === GoalManager::IDGOAL_CART; $allMetrics = Goals::getGoalColumns($idGoal); $columnsToShow = Piwik::getArrayFromApiParameter($columns); $requestedColumns = $columnsToShow; $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)); } $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(); } $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; }
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; }
/** * @internal param $this->getProcessor() */ public function aggregateMultipleReports() { /* * Archive Ecommerce Items */ $dataTableToSum = $this->dimensionRecord; foreach ($this->dimensionRecord as $recordName) { $dataTableToSum[] = self::getItemRecordNameAbandonedCart($recordName); } $columnsAggregationOperation = null; $this->getProcessor()->aggregateDataTableRecords($dataTableToSum, $maximumRowsInDataTableLevelZero = null, $maximumRowsInSubDataTable = null, $columnToSortByBeforeTruncation = null, $columnsAggregationOperation, $columnsToRenameAfterAggregation = null, $countRowsRecursive = array()); /* * Archive General Goal metrics */ $goalIdsToSum = GoalManager::getGoalIds($this->getProcessor()->getParams()->getSite()->getId()); //Ecommerce $goalIdsToSum[] = GoalManager::IDGOAL_ORDER; $goalIdsToSum[] = GoalManager::IDGOAL_CART; //bug here if idgoal=1 // Overall goal metrics $goalIdsToSum[] = false; $fieldsToSum = array(); foreach ($goalIdsToSum as $goalId) { $metricsToSum = Goals::getGoalColumns($goalId); foreach ($metricsToSum as $metricName) { $fieldsToSum[] = self::getRecordName($metricName, $goalId); } } $this->getProcessor()->aggregateNumericMetrics($fieldsToSum); $columnsAggregationOperation = null; foreach ($goalIdsToSum as $goalId) { // 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)), $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)), $maximumRowsInDataTableLevelZero = null, $maximumRowsInSubDataTable = null, $columnToSortByBeforeTruncation = null, $columnsAggregationOperation, $columnsToRenameAfterAggregation = null, $countRowsRecursive = array()); }