| /** | |
| * Matomo - free/libre analytics platform | |
| * | |
| * @link https://matomo.org | |
| * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later | |
| */ | |
| namespace Piwik\Plugins\Events; | |
| use Piwik\Archive; | |
| use Piwik\DataTable; | |
| use Piwik\Metrics; | |
| use Piwik\Piwik; | |
| /** | |
| * The Events API lets you request reports about your users' Custom Events. | |
| * | |
| * Events are tracked using the Javascript Tracker trackEvent() function, or using the [Tracking HTTP API](https://developer.matomo.org/api-reference/tracking-api). | |
| * | |
| * <br/>An event is defined by an event category (Videos, Music, Games...), | |
| * an event action (Play, Pause, Duration, Add Playlist, Downloaded, Clicked...), | |
| * and an optional event name (a movie name, a song title, etc.) and an optional numeric value. | |
| * | |
| * <br/>This API exposes the following Custom Events reports: `getCategory` lists the top Event Categories, | |
| * `getAction` lists the top Event Actions, `getName` lists the top Event Names. | |
| * | |
| * <br/>These Events report define the following metrics: nb_uniq_visitors, nb_visits, nb_events. | |
| * If you define values for your events, you can expect to see the following metrics: nb_events_with_value, | |
| * sum_event_value, min_event_value, max_event_value, avg_event_value | |
| * | |
| * <br/>The Events.get* reports can be used with an optional `&secondaryDimension` parameter. | |
| * Secondary dimension is the dimension used in the sub-table of the Event report you are requesting. | |
| * | |
| * <br/>Here are the possible values of `secondaryDimension`: <ul> | |
| * <li>For `Events.getCategory` you can set `secondaryDimension` to `eventAction` or `eventName`.</li> | |
| * <li>For `Events.getAction` you can set `secondaryDimension` to `eventName` or `eventCategory`.</li> | |
| * <li>For `Events.getName` you can set `secondaryDimension` to `eventAction` or `eventCategory`.</li> | |
| * </ul> | |
| * | |
| * <br/>For example, to request all Custom Events Categories, and for each, the top Event actions, | |
| * you would request: `method=Events.getCategory&secondaryDimension=eventAction&flat=1`. | |
| * You may also omit `&flat=1` in which case, to get top Event actions for one Event category, | |
| * use `method=Events.getActionFromCategoryId` passing it the `&idSubtable=` of this Event category. | |
| * | |
| * @method static \Piwik\Plugins\Events\API getInstance() | |
| */ | |
| class API extends \Piwik\Plugin\API | |
| { | |
| /** | |
| * @var array<string, string> | |
| */ | |
| protected $defaultMappingApiToSecondaryDimension = array( | |
| 'getCategory' => 'eventAction', | |
| 'getAction' => 'eventName', | |
| 'getName' => 'eventAction', | |
| ); | |
| /** | |
| * @var array<string, string|array<string, string>> | |
| */ | |
| protected $mappingApiToRecord = array( | |
| '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, | |
| 'getNameFromActionId' => Archiver::EVENTS_ACTION_NAME_RECORD_NAME, | |
| 'getActionFromNameId' => Archiver::EVENTS_NAME_ACTION_RECORD_NAME, | |
| 'getCategoryFromNameId' => Archiver::EVENTS_NAME_CATEGORY_RECORD_NAME, | |
| ); | |
| /** | |
| * @ignore | |
| * @param string $apiMethod | |
| * @param string|false $secondaryDimension | |
| * @return string|false | |
| */ | |
| public function getActionToLoadSubtables($apiMethod, $secondaryDimension = false) | |
| { | |
| $recordName = $this->getRecordNameForAction($apiMethod, $secondaryDimension); | |
| $apiMethod = array_search($recordName, $this->mappingApiToRecord); | |
| return $apiMethod; | |
| } | |
| /** | |
| * @ignore | |
| * @param string $apiMethod | |
| * @return string|false | |
| */ | |
| public function getDefaultSecondaryDimension($apiMethod) | |
| { | |
| if (isset($this->defaultMappingApiToSecondaryDimension[$apiMethod])) { | |
| return $this->defaultMappingApiToSecondaryDimension[$apiMethod]; | |
| } | |
| return false; | |
| } | |
| /** | |
| * @param string $apiMethod | |
| * @param string|false $secondaryDimension | |
| * @return string | |
| */ | |
| protected function getRecordNameForAction($apiMethod, $secondaryDimension = false) | |
| { | |
| if (empty($secondaryDimension)) { | |
| $secondaryDimension = $this->getDefaultSecondaryDimension($apiMethod); | |
| } | |
| $record = $this->mappingApiToRecord[$apiMethod]; | |
| if (!is_array($record)) { | |
| return $record; | |
| } | |
| // when secondaryDimension is incorrectly set | |
| if (empty($record[$secondaryDimension])) { | |
| return key($record); | |
| } | |
| return $record[$secondaryDimension]; | |
| } | |
| /** | |
| * @ignore | |
| * @param string $apiMethod | |
| * @return string[]|false | |
| */ | |
| public function getSecondaryDimensions($apiMethod) | |
| { | |
| $records = $this->mappingApiToRecord[$apiMethod]; | |
| if (!is_array($records)) { | |
| return false; | |
| } | |
| return array_keys($records); | |
| } | |
| /** | |
| * @param string|false $secondaryDimension | |
| */ | |
| protected function checkSecondaryDimension(string $apiMethod, $secondaryDimension): void | |
| { | |
| 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(", ", $this->getSecondaryDimensions($apiMethod) ?: []) | |
| ); | |
| } | |
| } | |
| /** | |
| * @param int|string|int[] $idSite | |
| * @param 'day'|'week'|'month'|'year'|'range' $period | |
| * @param string|null|false $segment | |
| * @param int|null|false $idSubtable | |
| * @param string|false $secondaryDimension | |
| * @return DataTable|DataTable\Map | |
| */ | |
| protected function getDataTable(string $name, $idSite, string $period, string $date, $segment, bool $expanded = false, $idSubtable = null, $secondaryDimension = false, bool $flat = false) | |
| { | |
| Piwik::checkUserHasViewAccess($idSite); | |
| $this->checkSecondaryDimension($name, $secondaryDimension); | |
| $recordName = $this->getRecordNameForAction($name, $secondaryDimension); | |
| $dataTable = Archive::createDataTableFromArchive($recordName, $idSite, $period, $date, $segment ?: '', $expanded, $flat, $idSubtable); | |
| $dataTable->filter(function ($dataTable) { | |
| $dataTable->setMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME, [ | |
| Metrics::INDEX_EVENT_MIN_EVENT_VALUE => 'min', | |
| Metrics::INDEX_EVENT_MAX_EVENT_VALUE => 'max', | |
| ]); | |
| }); | |
| if ($flat) { | |
| $dataTable->filterSubtables('Piwik\Plugins\Events\DataTable\Filter\ReplaceEventNameNotSet'); | |
| } else { | |
| $dataTable->filter('AddSegmentValue', array(function ($label) { | |
| if ($label === Archiver::EVENT_NAME_NOT_SET) { | |
| return false; | |
| } | |
| return $label; | |
| })); | |
| } | |
| $dataTable->filter('Piwik\Plugins\Events\DataTable\Filter\ReplaceEventNameNotSet'); | |
| return $dataTable; | |
| } | |
| /** | |
| * Returns event metrics grouped by event category. | |
| * | |
| * @param int|string|int[] $idSite Website ID(s) to query. | |
| * - Single site ID (e.g. 1) | |
| * - Multiple site IDs (e.g. [1, 4, 5]) | |
| * - Comma-separated list ("1,4,5") or "all" | |
| * @param 'day'|'week'|'month'|'year'|'range' $period The period to process, processes data for the period | |
| * containing the specified date. | |
| * @param string $date The date or date range to process. | |
| * 'YYYY-MM-DD', magic keywords (today, yesterday, lastWeek, lastMonth, lastYear), | |
| * or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD', lastX, previousX). | |
| * @param string|null|false $segment Custom segment to filter the report. | |
| * Example: "referrerName==example.com" | |
| * Supports AND (;) and OR (,) operators. | |
| * @param bool $expanded Whether subtables should be expanded in the response. | |
| * @param 'eventAction'|'eventName'|false $secondaryDimension Optional secondary dimension for subtable rows. | |
| * @param bool $flat Whether subtable rows should be flattened into a single table. | |
| * @return DataTable|DataTable\Map Event category metrics. | |
| */ | |
| public function getCategory($idSite, string $period, string $date, $segment = false, bool $expanded = false, $secondaryDimension = false, bool $flat = false) | |
| { | |
| return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded, false, $secondaryDimension, $flat); | |
| } | |
| /** | |
| * Returns event metrics grouped by event action. | |
| * | |
| * @param int|string|int[] $idSite Website ID(s) to query. | |
| * - Single site ID (e.g. 1) | |
| * - Multiple site IDs (e.g. [1, 4, 5]) | |
| * - Comma-separated list ("1,4,5") or "all" | |
| * @param 'day'|'week'|'month'|'year'|'range' $period The period to process, processes data for the period | |
| * containing the specified date. | |
| * @param string $date The date or date range to process. | |
| * 'YYYY-MM-DD', magic keywords (today, yesterday, lastWeek, lastMonth, lastYear), | |
| * or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD', lastX, previousX). | |
| * @param string|null|false $segment Custom segment to filter the report. | |
| * Example: "referrerName==example.com" | |
| * Supports AND (;) and OR (,) operators. | |
| * @param bool $expanded Whether subtables should be expanded in the response. | |
| * @param 'eventName'|'eventCategory'|false $secondaryDimension Optional secondary dimension for subtable rows. | |
| * @param bool $flat Whether subtable rows should be flattened into a single table. | |
| * @return DataTable|DataTable\Map Event action metrics. | |
| */ | |
| public function getAction($idSite, string $period, string $date, $segment = false, bool $expanded = false, $secondaryDimension = false, bool $flat = false) | |
| { | |
| return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded, false, $secondaryDimension, $flat); | |
| } | |
| /** | |
| * Returns event metrics grouped by event name. | |
| * | |
| * @param int|string|int[] $idSite Website ID(s) to query. | |
| * - Single site ID (e.g. 1) | |
| * - Multiple site IDs (e.g. [1, 4, 5]) | |
| * - Comma-separated list ("1,4,5") or "all" | |
| * @param 'day'|'week'|'month'|'year'|'range' $period The period to process, processes data for the period | |
| * containing the specified date. | |
| * @param string $date The date or date range to process. | |
| * 'YYYY-MM-DD', magic keywords (today, yesterday, lastWeek, lastMonth, lastYear), | |
| * or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD', lastX, previousX). | |
| * @param string|null|false $segment Custom segment to filter the report. | |
| * Example: "referrerName==example.com" | |
| * Supports AND (;) and OR (,) operators. | |
| * @param bool $expanded Whether subtables should be expanded in the response. | |
| * @param 'eventAction'|'eventCategory'|false $secondaryDimension Optional secondary dimension for subtable rows. | |
| * @param bool $flat Whether subtable rows should be flattened into a single table. | |
| * @return DataTable|DataTable\Map Event name metrics. | |
| */ | |
| public function getName($idSite, string $period, string $date, $segment = false, bool $expanded = false, $secondaryDimension = false, bool $flat = false) | |
| { | |
| return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, $expanded, false, $secondaryDimension, $flat); | |
| } | |
| /** | |
| * Returns event actions for one event category row. | |
| * | |
| * @param int|string|int[] $idSite Website ID(s) to query. | |
| * - Single site ID (e.g. 1) | |
| * - Multiple site IDs (e.g. [1, 4, 5]) | |
| * - Comma-separated list ("1,4,5") or "all" | |
| * @param 'day'|'week'|'month'|'year'|'range' $period The period to process, processes data for the period | |
| * containing the specified date. | |
| * @param string $date The date or date range to process. | |
| * 'YYYY-MM-DD', magic keywords (today, yesterday, lastWeek, lastMonth, lastYear), | |
| * or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD', lastX, previousX). | |
| * @param int $idSubtable Subtable ID for the event category row to expand. | |
| * @param string|null|false $segment Custom segment to filter the report. | |
| * Example: "referrerName==example.com" | |
| * Supports AND (;) and OR (,) operators. | |
| * @return DataTable|DataTable\Map Event action metrics for the selected category. | |
| */ | |
| public function getActionFromCategoryId($idSite, string $period, string $date, $idSubtable, $segment = false) | |
| { | |
| return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, false, $idSubtable); | |
| } | |
| /** | |
| * Returns event names for one event category row. | |
| * | |
| * @param int|string|int[] $idSite Website ID(s) to query. | |
| * - Single site ID (e.g. 1) | |
| * - Multiple site IDs (e.g. [1, 4, 5]) | |
| * - Comma-separated list ("1,4,5") or "all" | |
| * @param 'day'|'week'|'month'|'year'|'range' $period The period to process, processes data for the period | |
| * containing the specified date. | |
| * @param string $date The date or date range to process. | |
| * 'YYYY-MM-DD', magic keywords (today, yesterday, lastWeek, lastMonth, lastYear), | |
| * or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD', lastX, previousX). | |
| * @param int $idSubtable Subtable ID for the event category row to expand. | |
| * @param string|null|false $segment Custom segment to filter the report. | |
| * Example: "referrerName==example.com" | |
| * Supports AND (;) and OR (,) operators. | |
| * @return DataTable|DataTable\Map Event name metrics for the selected category. | |
| */ | |
| public function getNameFromCategoryId($idSite, string $period, string $date, $idSubtable, $segment = false) | |
| { | |
| return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, false, $idSubtable); | |
| } | |
| /** | |
| * Returns event categories for one event action row. | |
| * | |
| * @param int|string|int[] $idSite Website ID(s) to query. | |
| * - Single site ID (e.g. 1) | |
| * - Multiple site IDs (e.g. [1, 4, 5]) | |
| * - Comma-separated list ("1,4,5") or "all" | |
| * @param 'day'|'week'|'month'|'year'|'range' $period The period to process, processes data for the period | |
| * containing the specified date. | |
| * @param string $date The date or date range to process. | |
| * 'YYYY-MM-DD', magic keywords (today, yesterday, lastWeek, lastMonth, lastYear), | |
| * or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD', lastX, previousX). | |
| * @param int $idSubtable Subtable ID for the event action row to expand. | |
| * @param string|null|false $segment Custom segment to filter the report. | |
| * Example: "referrerName==example.com" | |
| * Supports AND (;) and OR (,) operators. | |
| * @return DataTable|DataTable\Map Event category metrics for the selected action. | |
| */ | |
| public function getCategoryFromActionId($idSite, string $period, string $date, $idSubtable, $segment = false) | |
| { | |
| return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, false, $idSubtable); | |
| } | |
| /** | |
| * Returns event names for one event action row. | |
| * | |
| * @param int|string|int[] $idSite Website ID(s) to query. | |
| * - Single site ID (e.g. 1) | |
| * - Multiple site IDs (e.g. [1, 4, 5]) | |
| * - Comma-separated list ("1,4,5") or "all" | |
| * @param 'day'|'week'|'month'|'year'|'range' $period The period to process, processes data for the period | |
| * containing the specified date. | |
| * @param string $date The date or date range to process. | |
| * 'YYYY-MM-DD', magic keywords (today, yesterday, lastWeek, lastMonth, lastYear), | |
| * or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD', lastX, previousX). | |
| * @param int $idSubtable Subtable ID for the event action row to expand. | |
| * @param string|null|false $segment Custom segment to filter the report. | |
| * Example: "referrerName==example.com" | |
| * Supports AND (;) and OR (,) operators. | |
| * @return DataTable|DataTable\Map Event name metrics for the selected action. | |
| */ | |
| public function getNameFromActionId($idSite, string $period, string $date, $idSubtable, $segment = false) | |
| { | |
| return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, false, $idSubtable); | |
| } | |
| /** | |
| * Returns event actions for one event name row. | |
| * | |
| * @param int|string|int[] $idSite Website ID(s) to query. | |
| * - Single site ID (e.g. 1) | |
| * - Multiple site IDs (e.g. [1, 4, 5]) | |
| * - Comma-separated list ("1,4,5") or "all" | |
| * @param 'day'|'week'|'month'|'year'|'range' $period The period to process, processes data for the period | |
| * containing the specified date. | |
| * @param string $date The date or date range to process. | |
| * 'YYYY-MM-DD', magic keywords (today, yesterday, lastWeek, lastMonth, lastYear), | |
| * or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD', lastX, previousX). | |
| * @param int $idSubtable Subtable ID for the event name row to expand. | |
| * @param string|null|false $segment Custom segment to filter the report. | |
| * Example: "referrerName==example.com" | |
| * Supports AND (;) and OR (,) operators. | |
| * @return DataTable|DataTable\Map Event action metrics for the selected name. | |
| */ | |
| public function getActionFromNameId($idSite, string $period, string $date, $idSubtable, $segment = false) | |
| { | |
| return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, false, $idSubtable); | |
| } | |
| /** | |
| * Returns event categories for one event name row. | |
| * | |
| * @param int|string|int[] $idSite Website ID(s) to query. | |
| * - Single site ID (e.g. 1) | |
| * - Multiple site IDs (e.g. [1, 4, 5]) | |
| * - Comma-separated list ("1,4,5") or "all" | |
| * @param 'day'|'week'|'month'|'year'|'range' $period The period to process, processes data for the period | |
| * containing the specified date. | |
| * @param string $date The date or date range to process. | |
| * 'YYYY-MM-DD', magic keywords (today, yesterday, lastWeek, lastMonth, lastYear), | |
| * or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD', lastX, previousX). | |
| * @param int $idSubtable Subtable ID for the event name row to expand. | |
| * @param string|null|false $segment Custom segment to filter the report. | |
| * Example: "referrerName==example.com" | |
| * Supports AND (;) and OR (,) operators. | |
| * @return DataTable|DataTable\Map Event category metrics for the selected name. | |
| */ | |
| public function getCategoryFromNameId($idSite, string $period, string $date, $idSubtable, $segment = false) | |
| { | |
| return $this->getDataTable(__FUNCTION__, $idSite, $period, $date, $segment, false, $idSubtable); | |
| } | |
| } | |