diff --git a/plugins/Events/API.php b/plugins/Events/API.php index 1ddbfdfee5cc622a0f90d73bbd50aec2e3a1a2fd..e1f629d683fc192190ea97fbcd738c873a86f211 100644 --- a/plugins/Events/API.php +++ b/plugins/Events/API.php @@ -9,8 +9,8 @@ namespace Piwik\Plugins\Events; use Piwik\Archive; -use Piwik\DataTable\Row; use Piwik\DataTable; +use Piwik\DataTable\Row; use Piwik\Metrics; use Piwik\Piwik; @@ -22,16 +22,28 @@ use Piwik\Piwik; */ class API extends \Piwik\Plugin\API { - protected $mappingApiToApiLoadsubtables = array( - 'getCategory' => 'getActionFromCategoryId', - 'getAction' => 'getNameFromActionId', - 'getName' => 'getActionFromNameId', + protected $defaultMappingApiToSecondaryDimension = array( + 'getCategory' => 'eventAction', + 'getAction' => 'eventName', + 'getName' => 'eventAction', ); protected $mappingApiToRecord = array( - 'getCategory' => Archiver::EVENTS_CATEGORY_ACTION_RECORD_NAME, - 'getAction' => Archiver::EVENTS_ACTION_NAME_RECORD_NAME, - 'getName' => Archiver::EVENTS_NAME_ACTION_RECORD_NAME, + 'getCategory' => + array( + 'eventAction' => Archiver::EVENTS_CATEGORY_ACTION_RECORD_NAME, + 'eventName' => Archiver::EVENTS_CATEGORY_NAME_RECORD_NAME, + ), + 'getAction' => + array( + 'eventName' => Archiver::EVENTS_ACTION_NAME_RECORD_NAME, + 'eventCategory' => Archiver::EVENTS_ACTION_CATEGORY_RECORD_NAME, + ), + 'getName' => + array( + 'eventAction' => Archiver::EVENTS_NAME_ACTION_RECORD_NAME, + 'eventCategory' => Archiver::EVENTS_NAME_CATEGORY_RECORD_NAME, + ), 'getActionFromCategoryId' => Archiver::EVENTS_CATEGORY_ACTION_RECORD_NAME, 'getNameFromCategoryId' => Archiver::EVENTS_CATEGORY_NAME_RECORD_NAME, 'getCategoryFromActionId' => Archiver::EVENTS_ACTION_CATEGORY_RECORD_NAME, @@ -43,84 +55,131 @@ class API extends \Piwik\Plugin\API /** * @ignore */ - public function getSubtableAction($apiMethod) + public function getActionToLoadSubtables($apiMethod) { - return $this->mappingApiToApiLoadsubtables[$apiMethod]; + $secondaryDimension = $this->getDefaultSecondaryDimension($apiMethod); + $recordName = $this->getRecordNameForAction($apiMethod, $secondaryDimension); + return array_search( $recordName, $this->mappingApiToRecord ); } - protected function getRecordNameForAction($apiMethod) + protected function getDefaultSecondaryDimension($apiMethod) { - return $this->mappingApiToRecord[$apiMethod]; + if(isset($this->defaultMappingApiToSecondaryDimension[$apiMethod])) { + return $this->defaultMappingApiToSecondaryDimension[$apiMethod]; + } + return false; } - protected function getDataTable($name, $idSite, $period, $date, $segment, $expanded = false, $idSubtable = null) + + protected function getRecordNameForAction($apiMethod, $secondaryDimension = false) { - Piwik::checkUserHasViewAccess($idSite); - $dataTable = Archive::getDataTableFromArchive($name, $idSite, $period, $date, $segment, $expanded, $idSubtable); - $dataTable->filter('Sort', array(Metrics::INDEX_NB_VISITS)); - $dataTable->queueFilter('ReplaceColumnNames'); - $dataTable->queueFilter('ReplaceSummaryRowLabel'); - $dataTable->filter(function (DataTable $table) { - $row = $table->getRowFromLabel(Archiver::EVENT_NAME_NOT_SET); - if($row) { - $row->setColumn('label', Piwik::translate(Archiver::EVENT_NAME_NOT_SET)); + if (empty($secondaryDimension)) { + $record = $this->mappingApiToRecord[$apiMethod]; + + if(!is_array($record)) { + return $record; } - }); + $secondaryDimension = $this->getDefaultSecondaryDimension($apiMethod); + } - // add processed metric avg_event_value - $dataTable->queueFilter('ColumnCallbackAddColumnQuotient', - array('avg_event_value', - 'sum_event_value', - 'nb_events_with_value', - $precision = 2, - $shouldSkipRows = true) - ); + return $this->mappingApiToRecord[$apiMethod][$secondaryDimension]; + } + + protected function checkSecondaryDimension($apiMethod, $secondaryDimension) + { + if (empty($secondaryDimension)) { + return; + } + + $isSecondaryDimensionValid = + isset($this->mappingApiToRecord[$apiMethod]) + && isset($this->mappingApiToRecord[$apiMethod][$secondaryDimension]); + + if (!$isSecondaryDimensionValid) { + throw new \Exception( + "Secondary dimension '$secondaryDimension' is not valid for the API $apiMethod. ". + "Use one of: " . implode(", ", array_keys($this->mappingApiToRecord[$apiMethod])) + ); + } + } + protected function getDataTable($name, $idSite, $period, $date, $segment, $expanded = false, $idSubtable = null, $secondaryDimension = false) + { + Piwik::checkUserHasViewAccess($idSite); + $this->checkSecondaryDimension($name, $secondaryDimension); + $recordName = $this->getRecordNameForAction($name, $secondaryDimension); + $dataTable = Archive::getDataTableFromArchive($recordName, $idSite, $period, $date, $segment, $expanded, $idSubtable); + $this->filterDataTable($dataTable); return $dataTable; } - public function getCategory($idSite, $period, $date, $segment = false, $expanded = false) + public function getCategory($idSite, $period, $date, $segment = false, $expanded = false, $secondaryDimension = false) { - return $this->getDataTable($this->getRecordNameForAction(__FUNCTION__), $idSite, $period, $date, $segment, $expanded); + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded, $idSubtable = false, $secondaryDimension); } - public function getAction($idSite, $period, $date, $segment = false, $expanded = false) + public function getAction($idSite, $period, $date, $segment = false, $expanded = false, $secondaryDimension = false) { - return $this->getDataTable($this->getRecordNameForAction(__FUNCTION__), $idSite, $period, $date, $segment, $expanded); + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded, $idSubtable = false, $secondaryDimension); } - public function getName($idSite, $period, $date, $segment = false, $expanded = false) + public function getName($idSite, $period, $date, $segment = false, $expanded = false, $secondaryDimension = false) { - return $this->getDataTable($this->getRecordNameForAction(__FUNCTION__), $idSite, $period, $date, $segment, $expanded); + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded, $idSubtable = false, $secondaryDimension); } public function getActionFromCategoryId($idSite, $period, $date, $idSubtable, $segment = false) { - return $this->getDataTable($this->getRecordNameForAction(__FUNCTION__), $idSite, $period, $date, $segment, $expanded = false, $idSubtable); + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded = false, $idSubtable); } public function getNameFromCategoryId($idSite, $period, $date, $idSubtable, $segment = false) { - return $this->getDataTable($this->getRecordNameForAction(__FUNCTION__), $idSite, $period, $date, $segment, $expanded = false, $idSubtable); + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded = false, $idSubtable); } public function getCategoryFromActionId($idSite, $period, $date, $idSubtable, $segment = false) { - return $this->getDataTable($this->getRecordNameForAction(__FUNCTION__), $idSite, $period, $date, $segment, $expanded = false, $idSubtable); + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded = false, $idSubtable); } public function getNameFromActionId($idSite, $period, $date, $idSubtable, $segment = false) { - return $this->getDataTable($this->getRecordNameForAction(__FUNCTION__), $idSite, $period, $date, $segment, $expanded = false, $idSubtable); + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded = false, $idSubtable); } public function getActionFromNameId($idSite, $period, $date, $idSubtable, $segment = false) { - return $this->getDataTable($this->getRecordNameForAction(__FUNCTION__), $idSite, $period, $date, $segment, $expanded = false, $idSubtable); + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded = false, $idSubtable); } public function getCategoryFromNameId($idSite, $period, $date, $idSubtable, $segment = false) { - return $this->getDataTable($this->getRecordNameForAction(__FUNCTION__), $idSite, $period, $date, $segment, $expanded = false, $idSubtable); + return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded = false, $idSubtable); + } + + /** + * @param DataTable $dataTable + */ + protected function filterDataTable($dataTable) + { + $dataTable->filter('Sort', array(Metrics::INDEX_NB_VISITS)); + $dataTable->queueFilter('ReplaceColumnNames'); + $dataTable->queueFilter('ReplaceSummaryRowLabel'); + $dataTable->filter(function (DataTable $table) { + $row = $table->getRowFromLabel(Archiver::EVENT_NAME_NOT_SET); + if ($row) { + $row->setColumn('label', Piwik::translate('General_NotDefined', Piwik::translate('Events_EventName'))); + } + }); + + // add processed metric avg_event_value + $dataTable->queueFilter('ColumnCallbackAddColumnQuotient', + array('avg_event_value', + 'sum_event_value', + 'nb_events_with_value', + $precision = 2, + $shouldSkipRows = true) + ); } } \ No newline at end of file diff --git a/plugins/Events/Archiver.php b/plugins/Events/Archiver.php index e7115d16c0e5a95e41592f99fca28ada16ef9f44..1289424b455d87a9a51235579931a52978700ff1 100644 --- a/plugins/Events/Archiver.php +++ b/plugins/Events/Archiver.php @@ -68,7 +68,7 @@ class Archiver extends \Piwik\Plugin\Archiver const EVENTS_ACTION_NAME_RECORD_NAME = 'Events_action_name'; const EVENTS_NAME_ACTION_RECORD_NAME = 'Events_name_action'; const EVENTS_NAME_CATEGORY_RECORD_NAME = 'Events_name_category'; - const EVENT_NAME_NOT_SET = 'Events_NameNotSet'; + const EVENT_NAME_NOT_SET = 'Piwik_EventNameNotSet'; /** * @var DataArray[] @@ -86,12 +86,12 @@ class Archiver extends \Piwik\Plugin\Archiver protected function getRecordToDimensions() { return array( - self::EVENTS_CATEGORY_ACTION_RECORD_NAME => array("event_category", "event_action"), - self::EVENTS_CATEGORY_NAME_RECORD_NAME => array("event_category", "event_name"), - self::EVENTS_ACTION_NAME_RECORD_NAME => array("event_action", "event_name"), - self::EVENTS_ACTION_CATEGORY_RECORD_NAME => array("event_action", "event_category"), - self::EVENTS_NAME_ACTION_RECORD_NAME => array("event_name", "event_action"), - self::EVENTS_NAME_CATEGORY_RECORD_NAME => array("event_name", "event_category"), + self::EVENTS_CATEGORY_ACTION_RECORD_NAME => array("eventCategory", "eventAction"), + self::EVENTS_CATEGORY_NAME_RECORD_NAME => array("eventCategory", "eventName"), + self::EVENTS_ACTION_NAME_RECORD_NAME => array("eventAction", "eventName"), + self::EVENTS_ACTION_CATEGORY_RECORD_NAME => array("eventAction", "eventCategory"), + self::EVENTS_NAME_ACTION_RECORD_NAME => array("eventName", "eventAction"), + self::EVENTS_NAME_CATEGORY_RECORD_NAME => array("eventName", "eventCategory"), ); } @@ -116,9 +116,9 @@ class Archiver extends \Piwik\Plugin\Archiver protected function aggregateDayEvents() { $select = " - log_action_event_category.name as event_category, - log_action_event_action.name as event_action, - log_action_event_name.name as event_name, + log_action_event_category.name as eventCategory, + log_action_event_action.name as eventAction, + log_action_event_name.name as eventName, count(distinct log_link_visit_action.idvisit) as `" . Metrics::INDEX_NB_VISITS . "`, count(distinct log_link_visit_action.idvisitor) as `" . Metrics::INDEX_NB_UNIQ_VISITORS . "`, @@ -171,7 +171,7 @@ class Archiver extends \Piwik\Plugin\Archiver if ($rankingQueryLimit > 0) { $rankingQuery = new RankingQuery($rankingQueryLimit); $rankingQuery->setOthersLabel(DataTable::LABEL_SUMMARY_ROW); - $rankingQuery->addLabelColumn(array('event_category', 'event_action', 'event_name')); + $rankingQuery->addLabelColumn(array('eventCategory', 'eventAction', 'eventName')); $rankingQuery->addColumn(array(Metrics::INDEX_NB_UNIQ_VISITORS)); $rankingQuery->addColumn(array(Metrics::INDEX_EVENT_NB_HITS, Metrics::INDEX_NB_VISITS, Metrics::INDEX_EVENT_NB_HITS_WITH_VALUE), 'sum'); $rankingQuery->addColumn(Metrics::INDEX_EVENT_SUM_EVENT_VALUE, 'sum'); @@ -242,7 +242,7 @@ class Archiver extends \Piwik\Plugin\Archiver $mainLabel = $row[$mainDimension]; // Event name is optional - if ($mainDimension == 'event_name' + if ($mainDimension == 'eventName' && empty($mainLabel)) { $mainLabel = self::EVENT_NAME_NOT_SET; } diff --git a/plugins/Events/Events.php b/plugins/Events/Events.php index f9ac53f6c044320dc6027d7c18921b3b44517d60..d53f22f8f7338a8f3931e95e9ab04c02c46d34d0 100644 --- a/plugins/Events/Events.php +++ b/plugins/Events/Events.php @@ -151,7 +151,7 @@ class Events extends \Piwik\Plugin 'metrics' => $metrics, 'metricsDocumentation' => $documentation, 'processedMetrics' => false, - 'actionToLoadSubTables' => API::getInstance()->getSubtableAction($action), + 'actionToLoadSubTables' => API::getInstance()->getActionToLoadSubtables($action), 'order' => $order++ ); @@ -220,7 +220,7 @@ class Events extends \Piwik\Plugin $view->config->addTranslation('label', $this->getColumnTranslation($apiMethod)); $view->config->addTranslations($this->getMetricTranslations()); $view->config->columns_to_display = array('label', 'nb_events', 'sum_event_value'); - $view->config->subtable_controller_action = API::getInstance()->getSubtableAction($apiMethod); + $view->config->subtable_controller_action = API::getInstance()->getActionToLoadSubtables($apiMethod); // Creates the tooltip message for Event Value column $tooltipCallback = function ($hits, $min, $max, $avg) { diff --git a/plugins/Events/lang/en.json b/plugins/Events/lang/en.json index 2e625c873e8eaf8b3ec45dac7847d0facbd46cfd..77caf785c563458bfa9748de36188976a4b13440 100644 --- a/plugins/Events/lang/en.json +++ b/plugins/Events/lang/en.json @@ -21,7 +21,6 @@ "MaxValueDocumentation": "The maximum value for this event", "AvgValueDocumentation": "The average of all values for this event", "EventsWithValueDocumentation": "Number of events where an Event value was set", - "NameNotSet": "(Event Name not set)", "EventValueTooltip": "Total Event value is the sum of %s events values %s between minimum of %s and maximum of %s.", "AvgEventValue": "Average Event value is: %s", "TopEvents": "Top Events", diff --git a/tests/PHPUnit/Integration/CustomEventsTest.php b/tests/PHPUnit/Integration/CustomEventsTest.php index 7cd9583753d569e902e29a30a25fbd5375140f26..181f1355ca412e21e35cfef033f12f48b9f6ef0a 100644 --- a/tests/PHPUnit/Integration/CustomEventsTest.php +++ b/tests/PHPUnit/Integration/CustomEventsTest.php @@ -58,14 +58,6 @@ class Test_Piwik_Integration_CustomEvents extends IntegrationTestCase 'setDateLastN' => false, 'testSuffix' => '')), - array($apiEventAndAction, array( - 'idSite' => $idSite1, - 'date' => $dateTime, - 'periods' => $dayPeriod, - 'segment' => "events>0", - 'setDateLastN' => false, - 'testSuffix' => '') - ), array($apiEventAndAction, array( 'idSite' => $idSite1, 'date' => $dateTime, @@ -115,6 +107,22 @@ class Test_Piwik_Integration_CustomEvents extends IntegrationTestCase 'testSuffix' => '_' . $api . '_lastN') ); } + + // Test secondary dimensions + $secondaryDimensions = array('eventCategory', 'eventAction', 'eventName'); + foreach($secondaryDimensions as $secondaryDimension) { + $result[] = array(array('Events'), array( + 'idSite' => $idSite1, + 'date' => $dateTime, + 'periods' => $periods, + 'otherRequestParameters' => array( + 'secondaryDimension' => $secondaryDimension + ), + 'setDateLastN' => false, + 'testSuffix' => '_secondaryDimensionIs' . ucfirst($secondaryDimension)) + ); + } + return $result; }