private function findFirstLevelReport() { foreach (Report::getAllReports() as $report) { $actionToLoadSubtables = $report->getActionToLoadSubTables(); if ($actionToLoadSubtables == $this->apiMethod && $this->apiModule == $report->getModule()) { return $report; } } return null; }
public function test_getAllReports_ShouldFindAllAvailableReports() { $this->loadExampleReportPlugin(); $this->loadMorePlugins(); $reports = Report::getAllReports(); $this->assertGreaterThan(20, count($reports)); foreach ($reports as $report) { $this->assertInstanceOf('Piwik\\Plugin\\Report', $report); } }
private static function getAllReportsWithGoalMetrics() { $reportsWithGoals = array(); foreach (Report::getAllReports() as $report) { if ($report->hasGoalMetrics()) { $reportsWithGoals[] = array('category' => $report->getCategory(), 'name' => $report->getName(), 'module' => $report->getModule(), 'action' => $report->getAction()); } } /** * Triggered when gathering all reports that contain Goal metrics. The list of reports * will be displayed on the left column of the bottom of every _Goals_ page. * * If plugins define reports that contain goal metrics (such as **conversions** or **revenue**), * they can use this event to make sure their reports can be viewed on Goals pages. * * **Example** * * public function getReportsWithGoalMetrics(&$reports) * { * $reports[] = array( * 'category' => Piwik::translate('MyPlugin_myReportCategory'), * 'name' => Piwik::translate('MyPlugin_myReportDimension'), * 'module' => 'MyPlugin', * 'action' => 'getMyReport' * ); * } * * @param array &$reportsWithGoals The list of arrays describing reports that have Goal metrics. * Each element of this array must be an array with the following * properties: * * - **category**: The report category. This should be a translated string. * - **name**: The report's translated name. * - **module**: The plugin the report is in, eg, `'UserCountry'`. * - **action**: The API method of the report, eg, `'getCountry'`. * @ignore * @deprecated since 2.5.0 */ Piwik::postEvent('Goals.getReportsWithGoalMetrics', array(&$reportsWithGoals)); return $reportsWithGoals; }
/** * Triggers a hook to ask plugins for available Reports. * Returns metadata information about each report (category, name, dimension, metrics, etc.) * * @param string $idSites Comma separated list of website Ids * @param bool|string $period * @param bool|Date $date * @param bool $hideMetricsDoc * @param bool $showSubtableReports * @return array */ public function getReportMetadata($idSites, $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false) { $idSites = Site::getIdSitesFromIdSitesString($idSites); if (!empty($idSites)) { Piwik::checkUserHasViewAccess($idSites); } // as they cache key contains a lot of information there would be an even better cache result by caching parts of // this huge method separately but that makes it also more complicated. leaving it like this for now. $key = $this->buildReportMetadataCacheKey($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports); $key = CacheId::pluginAware($key); $cache = PiwikCache::getTransientCache(); if ($cache->contains($key)) { return $cache->fetch($key); } $parameters = array('idSites' => $idSites, 'period' => $period, 'date' => $date); $availableReports = array(); foreach (Report::getAllReports() as $report) { $report->configureReportMetadata($availableReports, $parameters); } /** * Triggered when gathering metadata for all available reports. * * Plugins that define new reports should use this event to make them available in via * the metadata API. By doing so, the report will become available in scheduled reports * as well as in the Piwik Mobile App. In fact, any third party app that uses the metadata * API will automatically have access to the new report. * * @param string &$availableReports The list of available reports. Append to this list * to make a report available. * * Every element of this array must contain the following * information: * * - **category**: A translated string describing the report's category. * - **name**: The translated display title of the report. * - **module**: The plugin of the report. * - **action**: The API method that serves the report. * * The following information is optional: * * - **dimension**: The report's [dimension](/guides/all-about-analytics-data#dimensions) if any. * - **metrics**: An array mapping metric names with their display names. * - **metricsDocumentation**: An array mapping metric names with their * translated documentation. * - **processedMetrics**: The array of metrics in the report that are * calculated using existing metrics. Can be set to * `false` if the report contains no processed * metrics. * - **order**: The order of the report in the list of reports * with the same category. * * @param array $parameters Contains the values of the sites and period we are * getting reports for. Some reports depend on this data. * For example, Goals reports depend on the site IDs being * requested. Contains the following information: * * - **idSites**: The array of site IDs we are getting reports for. * - **period**: The period type, eg, `'day'`, `'week'`, `'month'`, * `'year'`, `'range'`. * - **date**: A string date within the period or a date range, eg, * `'2013-01-01'` or `'2012-01-01,2013-01-01'`. * * TODO: put dimensions section in all about analytics data * @deprecated since 2.5.0 Use Report Classes instead. * @ignore */ Piwik::postEvent('API.getReportMetadata', array(&$availableReports, $parameters)); // TODO we can remove this one once we remove API.getReportMetadata event (except hideMetricsDoc) foreach ($availableReports as &$availableReport) { // can be removed once we remove hook API.getReportMetadata if (!isset($availableReport['metrics'])) { $availableReport['metrics'] = Metrics::getDefaultMetrics(); } // can be removed once we remove hook API.getReportMetadata if (!isset($availableReport['processedMetrics'])) { $availableReport['processedMetrics'] = Metrics::getDefaultProcessedMetrics(); } if ($hideMetricsDoc) { unset($availableReport['metricsDocumentation']); } else { if (!isset($availableReport['metricsDocumentation'])) { // set metric documentation to default if it's not set // can be removed once we remove hook API.getReportMetadata $availableReport['metricsDocumentation'] = Metrics::getDefaultMetricsDocumentation(); } } } /** * Triggered after all available reports are collected. * * This event can be used to modify the report metadata of reports in other plugins. You * could, for example, add custom metrics to every report or remove reports from the list * of available reports. * * @param array &$availableReports List of all report metadata. Read the {@hook API.getReportMetadata} * docs to see what this array contains. * @param array $parameters Contains the values of the sites and period we are * getting reports for. Some report depend on this data. * For example, Goals reports depend on the site IDs being * request. Contains the following information: * * - **idSites**: The array of site IDs we are getting reports for. * - **period**: The period type, eg, `'day'`, `'week'`, `'month'`, * `'year'`, `'range'`. * - **date**: A string date within the period or a date range, eg, * `'2013-01-01'` or `'2012-01-01,2013-01-01'`. */ Piwik::postEvent('API.getReportMetadata.end', array(&$availableReports, $parameters)); // Sort results to ensure consistent order usort($availableReports, array('self', 'sortReports')); $knownMetrics = array_merge(Metrics::getDefaultMetrics(), Metrics::getDefaultProcessedMetrics()); $columnsToKeep = $this->getColumnsToKeep(); $columnsToRemove = $this->getColumnsToRemove(); foreach ($availableReports as &$availableReport) { // Ensure all metrics have a translation $metrics = $availableReport['metrics']; $cleanedMetrics = array(); // TODO we can remove this once we remove the getReportMetadata event, leaving it here for backwards compatibility foreach ($metrics as $metricId => $metricTranslation) { // When simply the column name was given, ie 'metric' => array( 'nb_visits' ) // $metricTranslation is in this case nb_visits. We look for a known translation. if (is_numeric($metricId) && isset($knownMetrics[$metricTranslation])) { $metricId = $metricTranslation; $metricTranslation = $knownMetrics[$metricTranslation]; } $cleanedMetrics[$metricId] = $metricTranslation; } $availableReport['metrics'] = $cleanedMetrics; // if hide/show columns specified, hide/show metrics & docs $availableReport['metrics'] = $this->hideShowMetricsWithParams($availableReport['metrics'], $columnsToRemove, $columnsToKeep); if (isset($availableReport['processedMetrics'])) { $availableReport['processedMetrics'] = $this->hideShowMetricsWithParams($availableReport['processedMetrics'], $columnsToRemove, $columnsToKeep); } if (isset($availableReport['metricsDocumentation'])) { $availableReport['metricsDocumentation'] = $this->hideShowMetricsWithParams($availableReport['metricsDocumentation'], $columnsToRemove, $columnsToKeep); } // Remove array elements that are false (to clean up API output) foreach ($availableReport as $attributeName => $attributeValue) { if (empty($attributeValue)) { unset($availableReport[$attributeName]); } } // when there are per goal metrics, don't display conversion_rate since it can differ from per goal sum // TODO we should remove this once we remove the getReportMetadata event, leaving it here for backwards compatibility if (isset($availableReport['metricsGoal'])) { unset($availableReport['processedMetrics']['conversion_rate']); unset($availableReport['metricsGoal']['conversion_rate']); } // Processing a uniqueId for each report, // can be used by UIs as a key to match a given report $uniqueId = $availableReport['module'] . '_' . $availableReport['action']; if (!empty($availableReport['parameters'])) { foreach ($availableReport['parameters'] as $key => $value) { $uniqueId .= '_' . $key . '--' . $value; } } $availableReport['uniqueId'] = $uniqueId; // Order is used to order reports internally, but not meant to be used outside unset($availableReport['order']); } // remove subtable reports if (!$showSubtableReports) { foreach ($availableReports as $idx => $report) { if (isset($report['isSubtableReport']) && $report['isSubtableReport']) { unset($availableReports[$idx]); } } } $actualReports = array_values($availableReports); $cache->save($key, $actualReports); return $actualReports; // make sure array has contiguous key values }
/** * Triggers the Menu.Reporting.addItems hook and returns the menu. * * @return Array */ public function getMenu() { if (!$this->menu) { /** * @ignore * @deprecated */ Piwik::postEvent('Menu.Reporting.addItems', array()); foreach (Report::getAllReports() as $report) { if ($report->isEnabled()) { $report->configureReportingMenu($this); } } foreach ($this->getAllMenus() as $menu) { $menu->configureReportingMenu($this); } } return parent::getMenu(); }
private static function addWidgets() { if (!self::$hookCalled) { self::$hookCalled = true; /** * @ignore * @deprecated */ Piwik::postEvent('WidgetsList.addWidgets'); $widgetsList = self::getInstance(); foreach (Report::getAllReports() as $report) { if ($report->isEnabled()) { $report->configureWidget($widgetsList); } } $widgetContainers = Widgets::getAllWidgets(); foreach ($widgetContainers as $widgetContainer) { $widgets = $widgetContainer->getWidgets(); foreach ($widgets as $widget) { $widgetsList->add($widget['category'], $widget['name'], $widget['module'], $widget['method'], $widget['params']); } } foreach ($widgetContainers as $widgetContainer) { $widgetContainer->configureWidgetsList($widgetsList); } } }
/** * @param InputInterface $input * @param OutputInterface $output * @param string $pluginName * @return array * @throws \RuntimeException */ protected function getDimension(InputInterface $input, OutputInterface $output, $pluginName) { $dimensions = array(); $dimensionNames = array(); foreach (Report::getAllReports() as $report) { $dimension = $report->getDimension(); if (is_object($dimension)) { $name = $dimension->getName(); if (!empty($name)) { $dimensions[$name] = get_class($dimension); $dimensionNames[] = $name; } } } $plugin = Manager::getInstance()->loadPlugin($pluginName); $dimensions = Dimension::getAllDimensions(); $dimensions = array_merge($dimensions, Dimension::getDimensions($plugin)); foreach ($dimensions as $dimension) { $name = $dimension->getName(); if (!empty($name)) { $dimensions[$name] = get_class($dimension); $dimensionNames[] = $name; } } $dimensionNames = array_values(array_unique($dimensionNames)); $validate = function ($dimension) use($dimensions) { if (empty($dimension)) { return ''; } if (!empty($dimension) && !array_key_exists($dimension, $dimensions)) { throw new \InvalidArgumentException('Leave dimension either empty or use an existing one. You can also create a new dimension by calling .console generate:dimension before generating this report.'); } return $dimension; }; $actualDimension = $input->getOption('dimension'); if (null === $actualDimension) { $dialog = $this->getHelperSet()->get('dialog'); $actualDimension = $dialog->askAndValidate($output, 'Enter the report dimension, for instance "Browser" (you can leave it either empty or use an existing one): ', $validate, false, null, $dimensionNames); } else { $validate($actualDimension); } if (empty($actualDimension)) { return array('null', ''); } $className = $dimensions[$actualDimension]; $parts = explode('\\', $className); $name = end($parts); return array('new ' . $name . '()', 'use ' . $className . ';'); }