matomo / plugins /Actions /API.php
Leon4gr45's picture
Upload source files chunk 13
2a0a63a verified
Raw
History Blame Contribute Delete
45.5 kB
<?php
/**
* 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\Actions;
use Exception;
use Piwik\Archive;
use Piwik\Common;
use Piwik\DataTable;
use Piwik\Metrics as PiwikMetrics;
use Piwik\Piwik;
use Piwik\Plugin\ProcessedMetric;
use Piwik\Plugins\Actions\Columns\Metrics\AveragePageGenerationTime;
use Piwik\Plugins\Actions\Columns\Metrics\AverageTimeOnPage;
use Piwik\Plugins\Actions\Columns\Metrics\BounceRate;
use Piwik\Plugins\Actions\Columns\Metrics\ExitRate;
use Piwik\Plugin\ReportsProvider;
use Piwik\Tracker\Action;
use Piwik\Tracker\PageUrl;
/**
* The Actions API lets you request reports for all your Visitor Actions: Page URLs, Page titles, Events, Content Tracking,
* File Downloads and Clicks on external websites.
*
* For example, "getPageTitles" will return all your page titles along with standard <a href='https://matomo.org/docs/analytics-api/reference/#toc-metric-definitions' rel='noreferrer' target='_blank'>Actions metrics</a> for each row.
*
* It is also possible to request data for a specific Page Title with "getPageTitle"
* and setting the parameter pageName to the page title you wish to request.
* Similarly, you can request metrics for a given Page URL via "getPageUrl", a Download file via "getDownload"
* and an outlink via "getOutlink".
*
* Note: pageName, pageUrl, outlinkUrl, downloadUrl parameters must be URL encoded before you call the API.
* @method static \Piwik\Plugins\Actions\API getInstance()
*/
class API extends \Piwik\Plugin\API
{
/**
* Returns aggregated action metrics for the requested site and period.
*
* @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 list<string>|string|false $columns Metrics to include in the response.
* Accepts a comma-separated list or array of metric names.
* @return DataTable|DataTable\Map Action metrics for the selected site, period, and segment.
*/
public function get($idSite, string $period, string $date, $segment = false, $columns = false)
{
Piwik::checkUserHasViewAccess($idSite);
/** @var Reports\Get $report */
$report = ReportsProvider::factory("Actions", "get");
$archive = Archive::build($idSite, $period, $date, $segment);
$requestedColumns = Piwik::getArrayFromApiParameter($columns);
$columns = $report->getMetricsRequiredForReport($allColumns = null, $requestedColumns);
$inDbColumnNames = array_map(function ($value) {
return 'Actions_' . $value;
}, $columns);
$dataTable = $archive->getDataTableFromNumeric($inDbColumnNames);
$dataTable->deleteColumns(array_diff($requestedColumns, $columns));
$newNameMapping = array_combine($inDbColumnNames, $columns);
$dataTable->filter('ReplaceColumnNames', [$newNameMapping]);
$columnsToShow = $requestedColumns ?: $report->getAllMetrics();
$dataTable->queueFilter('ColumnDelete', [$columnsToRemove = [], $columnsToShow]);
return $dataTable;
}
/**
* Returns page URL metrics for the requested site and period.
*
* @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 to expand all rows and include their subtables.
* @param int|null|false $idSubtable Subtable ID to fetch instead of the top-level report.
* @param int|null|false $depth Maximum depth of subtables to include when expanding results.
* @param bool $flat Whether to flatten the hierarchical URL report into a single table.
* @return DataTable|DataTable\Map Page URL metrics for the requested action rows.
*/
public function getPageUrls(
$idSite,
string $period,
string $date,
$segment = false,
bool $expanded = false,
$idSubtable = false,
$depth = false,
bool $flat = false
) {
Piwik::checkUserHasViewAccess($idSite);
$dataTable = Archive::createDataTableFromArchive('Actions_actions_url', $idSite, $period, $date, $segment, $expanded, $flat, $idSubtable, $depth);
$this->filterActionsDataTable($dataTable, Action::TYPE_PAGE_URL);
if ($flat) {
$dataTable->filter(function (DataTable $dataTable) {
$notDefinedUrl = ArchivingHelper::getUnknownActionName(Action::TYPE_PAGE_URL);
foreach ($dataTable->getRows() as $row) {
$label = (string)$row->getColumn('label');
if (substr($label, 0, 1) !== '/' && $label !== $notDefinedUrl) {
$row->setColumn('label', '/' . $label);
}
}
});
}
return $dataTable;
}
/**
* Returns page URL metrics for pages viewed immediately after an internal site search.
*
* @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 to expand all rows and include their subtables.
* @param int|null|false $idSubtable Subtable ID to fetch instead of the top-level report.
* @return DataTable|DataTable\Map Page URLs that followed an internal search.
*/
public function getPageUrlsFollowingSiteSearch($idSite, string $period, string $date, $segment = false, bool $expanded = false, $idSubtable = false)
{
Piwik::checkUserHasViewAccess($idSite);
$dataTable = $this->getPageUrls($idSite, $period, $date, $segment, $expanded, $idSubtable);
$this->keepPagesFollowingSearch($dataTable);
return $dataTable;
}
/**
* Returns page title metrics for pages viewed immediately after an internal site search.
*
* @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 to expand all rows and include their subtables.
* @param int|null|false $idSubtable Subtable ID to fetch instead of the top-level report.
* @return DataTable|DataTable\Map Page titles that followed an internal search.
*/
public function getPageTitlesFollowingSiteSearch($idSite, string $period, string $date, $segment = false, bool $expanded = false, $idSubtable = false)
{
Piwik::checkUserHasViewAccess($idSite);
$dataTable = $this->getPageTitles($idSite, $period, $date, $segment, $expanded, $idSubtable);
$this->keepPagesFollowingSearch($dataTable);
return $dataTable;
}
/**
* @param DataTable|DataTable\Map $dataTable
*/
protected function keepPagesFollowingSearch($dataTable): void
{
// Keep only pages which are following site search
$dataTable->filter('ColumnCallbackDeleteRow', [
PiwikMetrics::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS,
function ($value) {
return $value <= 0;
},
]);
}
/**
* Returns a DataTable with analytics information for every unique entry page URL, for
* the specified site, period & segment.
*
* @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 to expand all rows and include their subtables.
* @param int|null|false $idSubtable Subtable ID to fetch instead of the top-level report.
* @param bool $flat Whether to flatten the hierarchical URL report into a single table.
* @return DataTable|DataTable\Map Entry page URL metrics for the requested site.
*/
public function getEntryPageUrls(
$idSite,
string $period,
string $date,
$segment = false,
bool $expanded = false,
$idSubtable = false,
bool $flat = false
) {
Piwik::checkUserHasViewAccess($idSite);
$dataTable = $this->getPageUrls($idSite, $period, $date, $segment, $expanded, $idSubtable, false, $flat);
$this->filterNonEntryActions($dataTable);
return $dataTable;
}
/**
* Returns a DataTable with analytics information for every unique exit page URL, for
* the specified site, period & segment.
*
* @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 to expand all rows and include their subtables.
* @param int|null|false $idSubtable Subtable ID to fetch instead of the top-level report.
* @param bool $flat Whether to flatten the hierarchical URL report into a single table.
* @return DataTable|DataTable\Map Exit page URL metrics for the requested site.
*/
public function getExitPageUrls(
$idSite,
string $period,
string $date,
$segment = false,
bool $expanded = false,
$idSubtable = false,
bool $flat = false
) {
Piwik::checkUserHasViewAccess($idSite);
$dataTable = $this->getPageUrls($idSite, $period, $date, $segment, $expanded, $idSubtable, false, $flat);
$this->filterNonExitActions($dataTable);
return $dataTable;
}
/**
* Returns metrics for a specific page URL.
*
* @param string $pageUrl The URL-encoded page URL to look up.
* @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.
* @return DataTable|DataTable\Map Metrics for the requested page URL, or an empty table if it is not found.
*/
public function getPageUrl($pageUrl, $idSite, string $period, string $date, $segment = false)
{
Piwik::checkUserHasViewAccess($idSite);
$callBackParameters = ['Actions_actions_url', $idSite, $period, $date, $segment, $expanded = false, $flat = false, $idSubtable = null];
$dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $pageUrl, Action::TYPE_PAGE_URL);
$this->addPageProcessedMetrics($dataTable);
$this->filterActionsDataTable($dataTable, Action::TYPE_PAGE_URL);
return $dataTable;
}
/**
* Returns page title metrics for the requested site and period.
*
* @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 to expand all rows and include their subtables.
* @param int|null|false $idSubtable Subtable ID to fetch instead of the top-level report.
* @param bool $flat Whether to flatten the hierarchical title report into a single table.
* @return DataTable|DataTable\Map Page title metrics for the requested action rows.
*/
public function getPageTitles($idSite, string $period, string $date, $segment = false, bool $expanded = false, $idSubtable = false, bool $flat = false)
{
Piwik::checkUserHasViewAccess($idSite);
$dataTable = Archive::createDataTableFromArchive('Actions_actions', $idSite, $period, $date, $segment, $expanded, $flat, $idSubtable);
$this->filterActionsDataTable($dataTable, Action::TYPE_PAGE_TITLE);
return $dataTable;
}
/**
* Returns a DataTable with analytics information for every unique entry page title
* for the given site, time period & segment.
*
* @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 to expand all rows and include their subtables.
* @param int|null|false $idSubtable Subtable ID to fetch instead of the top-level report.
* @param bool $flat Whether to flatten the hierarchical title report into a single table.
* @return DataTable|DataTable\Map Entry page title metrics for the requested site.
*/
public function getEntryPageTitles(
$idSite,
string $period,
string $date,
$segment = false,
bool $expanded = false,
$idSubtable = false,
bool $flat = false
) {
Piwik::checkUserHasViewAccess($idSite);
$dataTable = $this->getPageTitles($idSite, $period, $date, $segment, $expanded, $idSubtable, $flat);
$this->filterNonEntryActions($dataTable);
return $dataTable;
}
/**
* Returns a DataTable with analytics information for every unique exit page title
* for the given site, time period & segment.
*
* @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 to expand all rows and include their subtables.
* @param int|null|false $idSubtable Subtable ID to fetch instead of the top-level report.
* @param bool $flat Whether to flatten the hierarchical title report into a single table.
* @return DataTable|DataTable\Map Exit page title metrics for the requested site.
*/
public function getExitPageTitles(
$idSite,
string $period,
string $date,
$segment = false,
bool $expanded = false,
$idSubtable = false,
bool $flat = false
) {
Piwik::checkUserHasViewAccess($idSite);
$dataTable = $this->getPageTitles($idSite, $period, $date, $segment, $expanded, $idSubtable, $flat);
$this->filterNonExitActions($dataTable);
return $dataTable;
}
/**
* Returns metrics for a specific page title.
*
* @param string $pageName The URL-encoded page title to look up.
* @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.
* @return DataTable|DataTable\Map Metrics for the requested page title, or an empty table if it is not found.
*/
public function getPageTitle($pageName, $idSite, string $period, string $date, $segment = false)
{
Piwik::checkUserHasViewAccess($idSite);
$callBackParameters = ['Actions_actions', $idSite, $period, $date, $segment, $expanded = false, $flat = false, $idSubtable = null];
$dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $pageName, Action::TYPE_PAGE_TITLE);
$this->addPageProcessedMetrics($dataTable);
$this->filterActionsDataTable($dataTable, Action::TYPE_PAGE_TITLE);
return $dataTable;
}
/**
* Returns download metrics for the requested site and period.
*
* @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 to expand all rows and include their subtables.
* @param int|null|false $idSubtable Subtable ID to fetch instead of the top-level report.
* @param bool $flat Whether to flatten the hierarchical download report into a single table.
* @return DataTable|DataTable\Map Download metrics for the requested action rows.
*/
public function getDownloads($idSite, string $period, string $date, $segment = false, bool $expanded = false, $idSubtable = false, bool $flat = false)
{
Piwik::checkUserHasViewAccess($idSite);
$dataTable = Archive::createDataTableFromArchive('Actions_downloads', $idSite, $period, $date, $segment, $expanded, $flat, $idSubtable);
$this->filterActionsDataTable($dataTable, Action::TYPE_DOWNLOAD);
return $dataTable;
}
/**
* Returns metrics for a specific download URL.
*
* @param string $downloadUrl The URL-encoded download URL to look up.
* @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.
* @return DataTable|DataTable\Map Metrics for the requested download URL, or an empty table if it is not found.
*/
public function getDownload($downloadUrl, $idSite, string $period, string $date, $segment = false)
{
Piwik::checkUserHasViewAccess($idSite);
$callBackParameters = ['Actions_downloads', $idSite, $period, $date, $segment, $expanded = false, $flat = false, $idSubtable = null];
$dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $downloadUrl, Action::TYPE_DOWNLOAD);
$this->filterActionsDataTable($dataTable, Action::TYPE_DOWNLOAD);
return $dataTable;
}
/**
* Returns outlink metrics for the requested site and period.
*
* @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 to expand all rows and include their subtables.
* @param int|null|false $idSubtable Subtable ID to fetch instead of the top-level report.
* @param bool $flat Whether to flatten the hierarchical outlink report into a single table.
* @return DataTable|DataTable\Map Outlink metrics for the requested action rows.
*/
public function getOutlinks($idSite, string $period, string $date, $segment = false, bool $expanded = false, $idSubtable = false, bool $flat = false)
{
Piwik::checkUserHasViewAccess($idSite);
$dataTable = Archive::createDataTableFromArchive('Actions_outlink', $idSite, $period, $date, $segment, $expanded, $flat, $idSubtable);
$this->filterActionsDataTable($dataTable, Action::TYPE_OUTLINK);
return $dataTable;
}
/**
* Returns metrics for a specific outlink URL.
*
* @param string $outlinkUrl The URL-encoded outlink URL to look up.
* @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.
* @return DataTable|DataTable\Map Metrics for the requested outlink URL, or an empty table if it is not found.
*/
public function getOutlink($outlinkUrl, $idSite, string $period, string $date, $segment = false)
{
Piwik::checkUserHasViewAccess($idSite);
$callBackParameters = ['Actions_outlink', $idSite, $period, $date, $segment, $expanded = false, $flat = false, $idSubtable = null];
$dataTable = $this->getFilterPageDatatableSearch($callBackParameters, $outlinkUrl, Action::TYPE_OUTLINK);
$this->filterActionsDataTable($dataTable, Action::TYPE_OUTLINK);
return $dataTable;
}
/**
* Returns internal search keywords that produced search results.
*
* @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.
* @return DataTable|DataTable\Map Site search keywords that returned at least one result.
*/
public function getSiteSearchKeywords($idSite, string $period, string $date, $segment = false)
{
Piwik::checkUserHasViewAccess($idSite);
$dataTable = $this->getSiteSearchKeywordsRaw($idSite, $period, $date, $segment);
$dataTable->deleteColumn(PiwikMetrics::INDEX_SITE_SEARCH_HAS_NO_RESULT);
$this->filterActionsDataTable($dataTable, Action::TYPE_SITE_SEARCH);
$dataTable->filter('ReplaceColumnNames');
$dataTable->filter('AddSegmentByLabel', ['siteSearchKeyword']);
$this->addPagesPerSearchColumn($dataTable);
return $dataTable;
}
/**
* Visitors can search, and then click "next" to view more results. This is the average number of search results pages viewed for this keyword.
*
* @param DataTable|DataTable\Simple|DataTable\Map $dataTable
* @param string $columnToRead
*/
protected function addPagesPerSearchColumn($dataTable, $columnToRead = 'nb_hits'): void
{
$dataTable->filter('ColumnCallbackAddColumnQuotient', ['nb_pages_per_search', $columnToRead, 'nb_visits', $precision = 1]);
}
/**
* Returns the raw internal site search keyword report before post-processing.
*
* @param int|string|int[] $idSite
* @param string|null|false $segment
* @return DataTable|DataTable\Map
*/
protected function getSiteSearchKeywordsRaw($idSite, string $period, string $date, $segment)
{
return Archive::createDataTableFromArchive('Actions_sitesearch', $idSite, $period, $date, $segment, $expanded = false);
}
/**
* Returns internal search keywords that produced no results.
*
* @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.
* @return DataTable|DataTable\Map Site search keywords that returned no results.
*/
public function getSiteSearchNoResultKeywords($idSite, string $period, string $date, $segment = false)
{
Piwik::checkUserHasViewAccess($idSite);
$dataTable = $this->getSiteSearchKeywordsRaw($idSite, $period, $date, $segment);
// Delete all rows that have some results
$dataTable->filter(
'ColumnCallbackDeleteRow',
[
PiwikMetrics::INDEX_SITE_SEARCH_HAS_NO_RESULT,
function ($value) {
return $value < 1;
},
]
);
$dataTable->deleteRow(DataTable::ID_SUMMARY_ROW);
$dataTable->deleteColumn(PiwikMetrics::INDEX_SITE_SEARCH_HAS_NO_RESULT);
$this->filterActionsDataTable($dataTable, $isPageTitleType = false);
$dataTable->filter('AddSegmentByLabel', ['siteSearchKeyword']);
$dataTable->filter('ReplaceColumnNames');
$this->addPagesPerSearchColumn($dataTable);
return $dataTable;
}
/**
* Returns internal search categories used by visitors on the site.
*
* @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.
* @return DataTable|DataTable\Map Site search categories and their metrics.
*/
public function getSiteSearchCategories($idSite, string $period, string $date, $segment = false)
{
Piwik::checkUserHasViewAccess($idSite);
$dataTable = Archive::createDataTableFromArchive('Actions_SiteSearchCategories', $idSite, $period, $date, $segment);
$dataTable->queueFilter('ColumnDelete', ['nb_uniq_visitors']);
$this->filterActionsDataTable($dataTable, $isPageTitleType = false);
$dataTable->filter('ReplaceColumnNames');
$dataTable->filter('AddSegmentValue');
$this->addPagesPerSearchColumn($dataTable, $columnToRead = 'nb_actions');
return $dataTable;
}
/**
* Searches an actions report for the first row whose label matches the requested value.
*
* @param list<mixed> $callBackParameters
* @param string $search
* @param int $actionType
* @return DataTable|DataTable\Map
*/
protected function getFilterPageDatatableSearch($callBackParameters, $search, $actionType)
{
// build the query parts that are searched inside the tree
if ($actionType == Action::TYPE_PAGE_TITLE) {
$searchedString = Common::unsanitizeInputValue($search);
} else {
$idSite = $callBackParameters[1];
try {
$searchedString = PageUrl::excludeQueryParametersFromUrl($search, $idSite);
} catch (Exception $e) {
$searchedString = $search;
}
}
ArchivingHelper::reloadConfig();
$searchTree = ArchivingHelper::getActionExplodedNames($searchedString, $actionType);
/** @var DataTable|DataTable\Map $table */
$table = call_user_func_array('\Piwik\Archive::createDataTableFromArchive', $callBackParameters);
if ($table instanceof DataTable\Map) {
// search an array of tables, e.g. when using date=last30
// note that if the root is an array, we filter all children
// if an array occurs inside the nested table, we only look for the first match (see below)
$dataTableMap = $table->getEmptyClone();
foreach ($table->getDataTables() as $label => $subTable) {
$newSubTable = $this->doFilterPageDatatableSearch($callBackParameters, $subTable, $searchTree);
$dataTableMap->addTable($newSubTable, $label);
}
return $dataTableMap;
}
return $this->doFilterPageDatatableSearch($callBackParameters, $table, $searchTree);
}
/**
* Traverses an actions report tree and returns the first matching row as a table.
*
* @FIXME This looks very similar to LabelFilter.php should it be refactored somehow?
*
* @param list<mixed> $callBackParameters
* @param DataTable|DataTable\Map $table
* @param list<string> $searchTree
* @return DataTable
*/
protected function doFilterPageDatatableSearch($callBackParameters, $table, $searchTree)
{
// filter a data table array
if ($table instanceof DataTable\Map) {
foreach ($table->getDataTables() as $subTable) {
$filteredSubTable = $this->doFilterPageDatatableSearch($callBackParameters, $subTable, $searchTree);
if ($filteredSubTable->getRowsCount() > 0) {
// match found in a sub table, return and stop searching the others
return $filteredSubTable;
}
}
// nothing found in all sub tables
$result = new DataTable();
$subTables = $table->getDataTables();
if (count($subTables) > 0) {
// use the first subtable's metadata to ensure basic metadata like `period` is available in response
$subTable = reset($subTables);
$result->setAllTableMetadata($subTable->getAllTableMetadata());
}
return $result;
}
// filter regular data table
if ($table instanceof DataTable) {
// search for the first part of the tree search
$search = array_shift($searchTree);
$row = $table->getRowFromLabel($search);
if ($row === false) {
// not found
$result = new DataTable();
$result->setAllTableMetadata($table->getAllTableMetadata());
return $result;
}
// end of tree search reached
if (count($searchTree) == 0) {
$result = $table->getEmptyClone();
$result->addRow($row);
$result->setAllTableMetadata($table->getAllTableMetadata());
return $result;
}
// match found on this level and more levels remaining: go deeper
$idSubTable = $row->getIdSubDataTable();
$callBackParameters[7] = $idSubTable;
/**
* @var \Piwik\Period|false $period
*/
$period = $table->getMetadata('period');
if (!empty($period)) {
$callBackParameters[3] = $period->getDateStart() . ',' . $period->getDateEnd();
}
$table = call_user_func_array('\Piwik\Archive::createDataTableFromArchive', $callBackParameters);
return $this->doFilterPageDatatableSearch($callBackParameters, $table, $searchTree);
}
}
/**
* Applies the shared post-processing filters used by Actions API reports.
*
* @template T of DataTable|DataTable\Map
*
* @param T $dataTable
* @param int|false $actionType Action type constant used to normalize labels and metadata.
* @return T
*/
private function filterActionsDataTable($dataTable, $actionType)
{
$dataTable->filter(function ($dataTable) {
$dataTable->setMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME, Metrics::getColumnsAggregationOperation());
});
// Must be applied before Sort in this case, since the DataTable can contain both int and strings indexes
// (in the transition period between pre 1.2 and post 1.2 datatable structure)
$dataTable->filter('Piwik\Plugins\Actions\DataTable\Filter\Actions', [$actionType]);
$dataTable->filter('Piwik\Plugins\Goals\DataTable\Filter\CalculateConversionPageRate');
return $dataTable;
}
/**
* Removes DataTable rows referencing actions that were never the first action of a visit.
*
* @param DataTable|DataTable\Map $dataTable
*/
private function filterNonEntryActions($dataTable): void
{
$dataTable->filter(
'ColumnCallbackDeleteRow',
[
PiwikMetrics::INDEX_PAGE_ENTRY_NB_VISITS,
function ($visits) {
return !strlen($visits);
},
]
);
}
/**
* Removes DataTable rows referencing actions that were never the last action of a visit.
*
* @param DataTable|DataTable\Map $dataTable
*/
private function filterNonExitActions($dataTable): void
{
$dataTable->filter(
'ColumnCallbackDeleteRow',
[
PiwikMetrics::INDEX_PAGE_EXIT_NB_VISITS,
function ($visits) {
return !strlen($visits);
},
]
);
}
private function addPageProcessedMetrics(DataTable\DataTableInterface $dataTable): void
{
$dataTable->filter(function (DataTable $table) {
/** @var ProcessedMetric[] $extraProcessedMetrics */
$extraProcessedMetrics = $table->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME) ?: [];
$extraProcessedMetrics[] = new AverageTimeOnPage();
$extraProcessedMetrics[] = new BounceRate();
$extraProcessedMetrics[] = new ExitRate();
$extraProcessedMetrics[] = new AveragePageGenerationTime();
$table->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, $extraProcessedMetrics);
});
}
}