| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\Plugins\Goals\Visualizations; |
|
|
| use Piwik\API\Request; |
| use Piwik\Common; |
| use Piwik\DataTable; |
| use Piwik\DataTable\Filter\AddColumnsProcessedMetricsGoal; |
| use Piwik\Piwik; |
| use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable; |
| use Piwik\Site; |
| use Piwik\Url; |
|
|
| require_once PIWIK_INCLUDE_PATH . '/core/Twig.php'; |
|
|
| |
| |
| |
| class Goals extends HtmlTable |
| { |
| public const ID = 'tableGoals'; |
| public const FOOTER_ICON = 'icon-goal'; |
| public const FOOTER_ICON_TITLE = 'General_DisplayTableWithGoalMetrics'; |
|
|
| public const GOALS_DISPLAY_NORMAL = 0; |
| public const GOALS_DISPLAY_PAGES = 1; |
| public const GOALS_DISPLAY_ENTRY_PAGES = 2; |
|
|
| private $displayType = self::GOALS_DISPLAY_NORMAL; |
|
|
| public function beforeLoadDataTable() |
| { |
| $request = $this->getRequestArray(); |
| $idGoal = $request['idGoal'] ?? null; |
|
|
| $requestMethod = $this->requestConfig->getApiModuleToRequest() . '.' . $this->requestConfig->getApiMethodToRequest(); |
| $idGoal = AddColumnsProcessedMetricsGoal::getProcessOnlyIdGoalToUseForReport($idGoal, $requestMethod); |
|
|
| if (!empty($idGoal)) { |
| $this->config->filters[] = ['Piwik\Plugins\Goals\DataTable\Filter\RemoveUnusedGoalRevenueColumns']; |
| $this->requestConfig->request_parameters_to_modify['idGoal'] = $idGoal; |
|
|
| if ($idGoal == AddColumnsProcessedMetricsGoal::GOALS_PAGES || $idGoal == AddColumnsProcessedMetricsGoal::GOALS_PAGES_ECOMMERCE) { |
| $this->displayType = self::GOALS_DISPLAY_PAGES; |
| } elseif ($idGoal == AddColumnsProcessedMetricsGoal::GOALS_ENTRY_PAGES || $idGoal == AddColumnsProcessedMetricsGoal::GOALS_ENTRY_PAGES_ECOMMERCE) { |
| $this->displayType = self::GOALS_DISPLAY_ENTRY_PAGES; |
| } |
| } |
|
|
| parent::beforeLoadDataTable(); |
|
|
| $this->config->show_totals_row = false; |
|
|
| if ($this->config->disable_subtable_when_show_goals) { |
| $this->config->subtable_controller_action = null; |
| $this->config->show_flatten_table = false; |
| $this->requestConfig->request_parameters_to_modify['flat'] = false; |
| } |
|
|
| $this->setShowGoalsColumnsProperties(); |
| } |
|
|
| public function beforeRender() |
| { |
| $this->config->show_totals_row = false; |
| $this->config->show_goals = true; |
| $this->config->show_goals_columns = true; |
| $this->config->datatable_css_class = 'dataTableVizGoals'; |
| $this->config->show_exclude_low_population = true; |
|
|
| if (1 == Common::getRequestVar('documentationForGoalsPage', 0, 'int')) { |
| |
| $this->config->documentation = Piwik::translate( |
| 'Goals_ConversionByTypeReportDocumentation', |
| ['<br />', '<br />', Url::getExternalLinkTag('https://matomo.org/docs/tracking-goals-web-analytics/'), '</a>'] |
| ); |
| } |
|
|
| if ($this->displayType == self::GOALS_DISPLAY_NORMAL) { |
| $this->config->metrics_documentation['nb_visits'] = Piwik::translate('Goals_ColumnVisits'); |
| } |
|
|
| if ($this->displayType == self::GOALS_DISPLAY_PAGES) { |
| $this->config->addTranslation('nb_visits', Piwik::translate('General_ColumnUniquePageviews')); |
| $this->config->metrics_documentation['nb_visits'] = Piwik::translate('General_ColumnUniquePageviewsDocumentation'); |
| $this->removeUnusedRevenueColumns(); |
| } |
|
|
| if ($this->displayType == self::GOALS_DISPLAY_ENTRY_PAGES) { |
| $this->config->metrics_documentation['entry_nb_visits'] = Piwik::translate('General_ColumnEntrancesDocumentation'); |
| $this->removeUnusedRevenueColumns(); |
| } |
|
|
| parent::beforeRender(); |
| } |
|
|
| |
| |
| |
| private function removeUnusedRevenueColumns() |
| { |
| if ($this->dataTable instanceof DataTable\DataTableInterface) { |
| foreach ($this->config->columns_to_display as $key => $column) { |
| if (false === strpos($column, 'revenue')) { |
| continue; |
| } |
| $columnValues = $this->dataTable->getColumn($column); |
| $columnValues = array_filter($columnValues); |
| if (empty($columnValues)) { |
| unset($this->config->columns_to_display[$key]); |
| } |
| } |
| } |
| } |
|
|
| private function setShowGoalsColumnsProperties() |
| { |
| |
| $idSite = Common::getRequestVar('idSite', null, 'int'); |
| $idGoal = Common::getRequestVar('idGoal', AddColumnsProcessedMetricsGoal::GOALS_OVERVIEW, 'string'); |
|
|
| $goalsToProcess = null; |
| if (Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER == $idGoal) { |
| $this->setPropertiesForEcommerceView(); |
|
|
| $goalsToProcess = [$idGoal]; |
| } elseif (AddColumnsProcessedMetricsGoal::GOALS_FULL_TABLE == $idGoal) { |
| $this->setPropertiesForGoals($idSite, 'all'); |
|
|
| $goalsToProcess = $this->getAllGoalIds($idSite); |
| } elseif (AddColumnsProcessedMetricsGoal::GOALS_OVERVIEW == $idGoal) { |
| $this->setPropertiesForGoalsOverview($idSite); |
|
|
| $goalsToProcess = $this->getAllGoalIds($idSite); |
| } else { |
| $this->setPropertiesForGoals($idSite, [$idGoal]); |
|
|
| $goalsToProcess = [$idGoal]; |
| } |
|
|
| |
| $this->requestConfig->request_parameters_to_modify['filter_update_columns_when_show_all_goals'] = $idGoal; |
| $this->requestConfig->request_parameters_to_modify['filter_show_goal_columns_process_goals'] = implode(',', $goalsToProcess); |
| } |
|
|
| private function setPropertiesForEcommerceView() |
| { |
| $this->requestConfig->filter_sort_order = 'desc'; |
|
|
| switch ($this->displayType) { |
| case self::GOALS_DISPLAY_NORMAL: |
| $this->requestConfig->filter_sort_column = 'goal_ecommerceOrder_revenue'; |
| $this->config->columns_to_display = [ |
| 'label', |
| 'nb_visits', |
| 'goal_ecommerceOrder_nb_conversions', |
| 'goal_ecommerceOrder_revenue', |
| 'goal_ecommerceOrder_conversion_rate', |
| 'goal_ecommerceOrder_avg_order_revenue', |
| 'goal_ecommerceOrder_items', |
| 'goal_ecommerceOrder_revenue_per_visit', |
| ]; |
| break; |
| case self::GOALS_DISPLAY_PAGES: |
| $this->requestConfig->filter_sort_column = 'goal_ecommerceOrder_revenue_attrib'; |
| $this->config->columns_to_display = [ |
| 'label', |
| 'nb_visits', |
| 'goal_ecommerceOrder_nb_conversions_attrib', |
| 'goal_ecommerceOrder_revenue_attrib', |
| 'goal_ecommerceOrder_nb_conversions_page_rate', |
| ]; |
| break; |
| case self::GOALS_DISPLAY_ENTRY_PAGES: |
| $this->requestConfig->filter_sort_column = 'goal_ecommerceOrder_revenue_entry'; |
| $this->config->columns_to_display = [ |
| 'label', |
| 'entry_nb_visits', |
| 'goal_ecommerceOrder_nb_conversions_entry', |
| 'goal_ecommerceOrder_revenue_entry', |
| 'goal_ecommerceOrder_nb_conversions_entry_rate', |
| 'goal_ecommerceOrder_revenue_per_entry', |
| ]; |
| break; |
| default: |
| $this->requestConfig->filter_sort_column = 'goal_ecommerceOrder_revenue'; |
| $this->config->columns_to_display = [ |
| 'label', |
| 'nb_visits', |
| 'goal_ecommerceOrder_nb_conversions', |
| 'goal_ecommerceOrder_revenue', |
| 'goal_ecommerceOrder_conversion_rate', |
| 'goal_ecommerceOrder_avg_order_revenue', |
| 'goal_ecommerceOrder_items', |
| 'goal_ecommerceOrder_revenue_per_visit', |
| ]; |
| } |
|
|
| $this->config->translations = array_merge($this->config->translations, [ |
| 'goal_ecommerceOrder_nb_conversions' => Piwik::translate('General_EcommerceOrders'), |
| 'goal_ecommerceOrder_revenue' => Piwik::translate('General_TotalRevenue'), |
| 'goal_ecommerceOrder_revenue_per_visit' => Piwik::translate('General_ColumnValuePerVisit'), |
| ]); |
|
|
| $goalName = Piwik::translate('General_EcommerceOrders'); |
| $this->config->metrics_documentation['revenue_per_visit'] = |
| Piwik::translate('Goals_ColumnRevenuePerVisitDocumentation', $goalName); |
| } |
|
|
| protected function setPropertiesForGoalsOverview($idSite) |
| { |
| $allGoals = $this->getGoals($idSite); |
|
|
| |
| if ($this->displayType == self::GOALS_DISPLAY_NORMAL) { |
| $this->config->columns_to_display = ['label', 'nb_visits']; |
|
|
| foreach ($allGoals as $goal) { |
| $column = "goal_{$goal['idgoal']}_conversion_rate"; |
| $this->config->columns_to_display[] = $column; |
| } |
|
|
| $this->config->columns_to_display[] = 'revenue_per_visit'; |
| } |
|
|
| if ($this->displayType == self::GOALS_DISPLAY_PAGES) { |
| $this->config->columns_to_display = ['label', 'nb_visits']; |
| $goalColumnTemplates = [ |
| 'goal_%s_nb_conversions_attrib', |
| 'goal_%s_revenue_attrib', |
| 'goal_%s_nb_conversions_page_rate', |
| ]; |
|
|
| |
| |
| foreach ($allGoals as $goal) { |
| foreach ($goalColumnTemplates as $columnTemplate) { |
| $this->config->columns_to_display[] = sprintf($columnTemplate, $goal['idgoal']); |
| } |
| } |
| } |
|
|
| if ($this->displayType == self::GOALS_DISPLAY_ENTRY_PAGES) { |
| $this->config->columns_to_display = ['label', 'entry_nb_visits']; |
|
|
| $goalColumnTemplates = [ |
| 'goal_%s_nb_conversions_entry', |
| 'goal_%s_nb_conversions_entry_rate', |
| 'goal_%s_revenue_entry', |
| 'goal_%s_revenue_per_entry', |
| ]; |
|
|
| |
| |
| foreach ($allGoals as $goal) { |
| foreach ($goalColumnTemplates as $columnTemplate) { |
| $this->config->columns_to_display[] = sprintf($columnTemplate, $goal['idgoal']); |
| } |
| } |
| } |
| } |
|
|
| protected function setPropertiesForGoals($idSite, $idGoals) |
| { |
| $allGoals = $this->getGoals($idSite); |
|
|
| if ($this->displayType == self::GOALS_DISPLAY_NORMAL) { |
| if ('all' == $idGoals) { |
| $idGoals = array_keys($allGoals); |
| } else { |
| |
| $this->requestConfig->filter_sort_column = 'goal_' . reset($idGoals) . '_nb_conversions'; |
| $this->requestConfig->filter_sort_order = 'desc'; |
| } |
|
|
| $this->config->columns_to_display = ['label', 'nb_visits']; |
|
|
| $goalColumnTemplates = [ |
| 'goal_%s_nb_conversions', |
| 'goal_%s_conversion_rate', |
| 'goal_%s_revenue', |
| 'goal_%s_revenue_per_visit', |
| ]; |
|
|
| |
| |
| foreach ($goalColumnTemplates as $columnTemplate) { |
| foreach ($idGoals as $idGoal) { |
| $this->config->columns_to_display[] = sprintf($columnTemplate, $idGoal); |
| } |
| } |
|
|
| $this->config->columns_to_display[] = 'revenue_per_visit'; |
| } |
|
|
| if ($this->displayType == self::GOALS_DISPLAY_PAGES) { |
| if ('all' === $idGoals) { |
| $idGoals = array_keys($allGoals); |
| $this->requestConfig->filter_sort_column = 'nb_visits'; |
| } else { |
| |
| $this->requestConfig->filter_sort_column = 'goal_' . reset($idGoals) . '_nb_conversions_attrib'; |
| } |
| $this->requestConfig->filter_sort_order = 'desc'; |
|
|
| $this->config->columns_to_display = ['label', 'nb_visits']; |
| $goalColumnTemplates = [ |
| 'goal_%s_nb_conversions_attrib', |
| 'goal_%s_revenue_attrib', |
| 'goal_%s_nb_conversions_page_rate', |
| ]; |
|
|
| |
| |
| foreach ($idGoals as $idGoal) { |
| foreach ($goalColumnTemplates as $columnTemplate) { |
| $this->config->columns_to_display[] = sprintf($columnTemplate, $idGoal); |
| } |
| } |
| } |
|
|
| if ($this->displayType == self::GOALS_DISPLAY_ENTRY_PAGES) { |
| if ('all' === $idGoals) { |
| $idGoals = array_keys($allGoals); |
| $this->requestConfig->filter_sort_column = 'entry_nb_visits'; |
| } else { |
| |
| $this->requestConfig->filter_sort_column = 'goal_' . reset($idGoals) . '_nb_conversions_entry'; |
| } |
| $this->requestConfig->filter_sort_order = 'desc'; |
| $this->config->columns_to_display = ['label', 'entry_nb_visits']; |
| $goalColumnTemplates = [ |
| 'goal_%s_nb_conversions_entry', |
| 'goal_%s_nb_conversions_entry_rate', |
| 'goal_%s_revenue_entry', |
| 'goal_%s_revenue_per_entry', |
| ]; |
|
|
| foreach ($idGoals as $idGoal) { |
| foreach ($goalColumnTemplates as $columnTemplate) { |
| $this->config->columns_to_display[] = sprintf($columnTemplate, $idGoal); |
| } |
| } |
| } |
| } |
|
|
| protected $goalsForCurrentSite = null; |
|
|
| protected function getGoals($idSite) |
| { |
| if ($this->goalsForCurrentSite === null) { |
| |
| $allGoals = []; |
|
|
| |
| if (Site::isEcommerceEnabledFor($idSite)) { |
| $ecommerceGoal = [ |
| 'idgoal' => Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER, |
| 'name' => Piwik::translate('Goals_EcommerceOrder'), |
| 'quoted_name' => false, |
| ]; |
| $allGoals[$ecommerceGoal['idgoal']] = $ecommerceGoal; |
| } |
|
|
| |
| $siteGoals = Request::processRequest('Goals.getGoals', ['idSite' => $idSite, 'filter_limit' => '-1', 'orderByName' => true], $default = []); |
|
|
| foreach ($siteGoals as &$goal) { |
| $goal['quoted_name'] = '"' . $goal['name'] . '"'; |
| $allGoals[$goal['idgoal']] = $goal; |
| } |
|
|
| $this->goalsForCurrentSite = $allGoals; |
| } |
|
|
| return $this->goalsForCurrentSite; |
| } |
|
|
| protected function getAllGoalIds($idSite) |
| { |
| $allGoals = $this->getGoals($idSite); |
| return array_map(function ($data) { |
| return $data['idgoal']; |
| }, $allGoals); |
| } |
| } |
|
|