public function test_pluginAware_shouldAppendLoadedPluginsAndLanguage()
 {
     $result = CacheId::pluginAware('myrandomkey');
     $parts = explode('-', $result);
     $this->assertCount(3, $parts);
     $this->assertEquals('myrandomkey', $parts[0]);
     $this->assertEquals(32, strlen($parts[1]), $parts[1] . ' is not a MD5 hash');
     $this->assertEquals('en', $parts[2]);
 }
Beispiel #2
0
 private static function getMapOfModuleActionsToReport()
 {
     $cacheId = CacheId::pluginAware('ReportFactoryMap');
     $cache = PiwikCache::getEagerCache();
     if ($cache->contains($cacheId)) {
         $mapApiToReport = $cache->fetch($cacheId);
     } else {
         $reports = new static();
         $reports = $reports->getAllReports();
         $mapApiToReport = array();
         foreach ($reports as $report) {
             $key = $report->getModule() . '.' . ucfirst($report->getAction());
             if (isset($mapApiToReport[$key]) && $report->getParameters()) {
                 // sometimes there are multiple reports with same module/action but different parameters.
                 // we might pick the "wrong" one. At some point we should compare all parameters and if there is
                 // a report which parameters mach $_REQUEST then we should prefer that report
                 continue;
             }
             $mapApiToReport[$key] = get_class($report);
         }
         $cache->save($cacheId, $mapApiToReport);
     }
     return $mapApiToReport;
 }
Beispiel #3
0
 public static function getDefaultMetricsDocumentation()
 {
     $cacheId = CacheId::pluginAware('DefaultMetricsDocumentation');
     $cache = PiwikCache::getTransientCache();
     if ($cache->contains($cacheId)) {
         return $cache->fetch($cacheId);
     }
     $translations = array('nb_visits' => 'General_ColumnNbVisitsDocumentation', 'nb_uniq_visitors' => 'General_ColumnNbUniqVisitorsDocumentation', 'nb_actions' => 'General_ColumnNbActionsDocumentation', 'nb_users' => 'General_ColumnNbUsersDocumentation', 'nb_actions_per_visit' => 'General_ColumnActionsPerVisitDocumentation', 'avg_time_on_site' => 'General_ColumnAvgTimeOnSiteDocumentation', 'bounce_rate' => 'General_ColumnBounceRateDocumentation', 'conversion_rate' => 'General_ColumnConversionRateDocumentation', 'avg_time_on_page' => 'General_ColumnAverageTimeOnPageDocumentation', 'nb_hits' => 'General_ColumnPageviewsDocumentation', 'exit_rate' => 'General_ColumnExitRateDocumentation');
     /**
      * Use this event to register translations for metrics documentation processed by your plugin.
      *
      * @param string[] $translations The array mapping of column_name => Plugin_TranslationForColumnDocumentation
      */
     Piwik::postEvent('Metrics.getDefaultMetricDocumentationTranslations', array(&$translations));
     $translations = array_map(array('\\Piwik\\Piwik', 'translate'), $translations);
     $cache->save($cacheId, $translations);
     return $translations;
 }
 /**
  * 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
 }
Beispiel #5
0
 private function getCacheId($idSite)
 {
     return CacheId::pluginAware('Goals.getGoals.' . $idSite);
 }
 /**
  * Get all conversion dimensions that are defined by all activated plugins.
  * @ignore
  */
 public static function getAllDimensions()
 {
     $cacheId = CacheId::pluginAware('ConversionDimensions');
     $cache = PiwikCache::getTransientCache();
     if (!$cache->contains($cacheId)) {
         $plugins = PluginManager::getInstance()->getPluginsLoadedAndActivated();
         $instances = array();
         foreach ($plugins as $plugin) {
             foreach (self::getDimensions($plugin) as $instance) {
                 $instances[] = $instance;
             }
         }
         $cache->save($cacheId, $instances);
     }
     return $cache->fetch($cacheId);
 }
 private static function getCacheId()
 {
     return CacheId::pluginAware('WidgetsList');
 }
Beispiel #8
0
 private static function getMapOfModuleActionsToReport()
 {
     $cacheId = CacheId::pluginAware('ReportFactoryMap');
     $cache = Cache::getEagerCache();
     if ($cache->contains($cacheId)) {
         $mapApiToReport = $cache->fetch($cacheId);
     } else {
         $reports = self::getAllReports();
         $mapApiToReport = array();
         foreach ($reports as $report) {
             $key = $report->getModule() . '.' . ucfirst($report->getAction());
             $mapApiToReport[$key] = get_class($report);
         }
         $cache->save($cacheId, $mapApiToReport);
     }
     return $mapApiToReport;
 }
Beispiel #9
0
 /**
  * Gets an instance of all available visit, action and conversion dimension.
  * @return Dimension[]
  */
 public static function getAllDimensions()
 {
     $cacheId = CacheId::pluginAware('AllDimensions');
     $cache = PiwikCache::getTransientCache();
     if (!$cache->contains($cacheId)) {
         $plugins = PluginManager::getInstance()->getPluginsLoadedAndActivated();
         $instances = array();
         /**
          * Triggered to add new dimensions that cannot be picked up automatically by the platform.
          * This is useful if the plugin allows a user to create reports / dimensions dynamically. For example
          * CustomDimensions or CustomVariables. There are a variable number of dimensions in this case and it
          * wouldn't be really possible to create a report file for one of these dimensions as it is not known
          * how many Custom Dimensions will exist.
          *
          * **Example**
          *
          *     public function addDimension(&$dimensions)
          *     {
          *         $dimensions[] = new MyCustomDimension();
          *     }
          *
          * @param Dimension[] $reports An array of dimensions
          */
         Piwik::postEvent('Dimension.addDimensions', array(&$instances));
         foreach ($plugins as $plugin) {
             foreach (self::getDimensions($plugin) as $instance) {
                 $instances[] = $instance;
             }
         }
         /**
          * Triggered to filter / restrict dimensions.
          *
          * **Example**
          *
          *     public function filterDimensions(&$dimensions)
          *     {
          *         foreach ($dimensions as $index => $dimension) {
          *              if ($dimension->getName() === 'Page URL') {}
          *                  unset($dimensions[$index]); // remove this dimension
          *              }
          *         }
          *     }
          *
          * @param Dimension[] $dimensions An array of dimensions
          */
         Piwik::postEvent('Dimension.filterDimensions', array(&$instances));
         $cache->save($cacheId, $instances);
     }
     return $cache->fetch($cacheId);
 }
 private function setDimensionsWithOnNewVisit($dimensionOnNewVisitResults)
 {
     $dimensions = array();
     foreach ($dimensionOnNewVisitResults as $onNewVisitResult) {
         $dim = $this->getMock('Piwik\\Plugin\\Dimension', array('shouldForceNewVisit', 'getColumnName'));
         $dim->expects($this->any())->method('shouldForceNewVisit')->will($this->returnValue($onNewVisitResult));
         $dimensions[] = $dim;
     }
     $cache = Cache::getTransientCache();
     $cache->save(CacheId::pluginAware('VisitDimensions'), $dimensions);
     Visit::$dimensions = null;
 }
Beispiel #11
0
 public function getSegmentsMetadata($idSites = array(), $_hideImplementationData = true)
 {
     if (empty($idSites)) {
         Piwik::checkUserHasSomeViewAccess();
     } else {
         Piwik::checkUserHasViewAccess($idSites);
     }
     $isNotAnonymous = !Piwik::isUserIsAnonymous();
     $sites = is_array($idSites) ? implode('.', $idSites) : (int) $idSites;
     $cache = Cache::getTransientCache();
     $cachKey = 'API.getSegmentsMetadata' . $sites . '_' . (int) $_hideImplementationData . '_' . (int) $isNotAnonymous;
     $cachKey = CacheId::pluginAware($cachKey);
     if ($cache->contains($cachKey)) {
         return $cache->fetch($cachKey);
     }
     $metadata = new SegmentMetadata();
     $segments = $metadata->getSegmentsMetadata($idSites, $_hideImplementationData, $isNotAnonymous);
     $cache->save($cachKey, $segments);
     return $segments;
 }
Beispiel #12
0
 /**
  * Triggers a hook to ask plugins for available Reports.
  * Returns metadata information about each report (category, name, dimension, metrics, etc.)
  *
  * @param int $idSite
  * @param bool|string $period
  * @param bool|Date $date
  * @param bool $hideMetricsDoc
  * @param bool $showSubtableReports
  * @return array
  */
 public function getReportMetadata($idSite, $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false)
 {
     Piwik::checkUserHasViewAccess($idSite);
     // 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($idSite, $period, $date, $hideMetricsDoc, $showSubtableReports);
     $key = CacheId::pluginAware($key);
     $cache = PiwikCache::getTransientCache();
     if ($cache->contains($key)) {
         return $cache->fetch($key);
     }
     $parameters = array('idSite' => $idSite, 'period' => $period, 'date' => $date);
     $availableReports = array();
     foreach ($this->reportsProvider->getAllReports() as $report) {
         $report->configureReportMetadata($availableReports, $parameters);
     }
     foreach ($availableReports as &$availableReport) {
         if ($hideMetricsDoc) {
             unset($availableReport['metricsDocumentation']);
         }
     }
     /**
      * 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($this, 'sortReports'));
     $knownMetrics = array_merge(Metrics::getDefaultMetrics(), Metrics::getDefaultProcessedMetrics());
     $columnsToKeep = $this->getColumnsToKeep();
     $columnsToRemove = $this->getColumnsToRemove();
     foreach ($availableReports as &$availableReport) {
         $availableReport['category'] = Piwik::translate($availableReport['category']);
         $availableReport['subcategory'] = Piwik::translate($availableReport['subcategory']);
         // 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
 }