/**
  * Constructor.
  */
 public function __construct($apiModule, $apiMethod, $request)
 {
     $this->apiModule = $apiModule;
     $this->apiMethod = $apiMethod;
     $this->setRequest($request);
     $this->report = Report::factory($apiModule, $apiMethod);
     $this->apiInconsistencies = new Inconsistencies();
     $this->setFormatter(new Formatter());
 }
Beispiel #2
0
 public function renderReportWidget($reportModule = null, $reportAction = null)
 {
     Piwik::checkUserHasSomeViewAccess();
     $this->checkSitePermission();
     $report = Report::factory($reportModule, $reportAction);
     if (empty($report)) {
         throw new Exception(Piwik::translate('General_ExceptionReportNotFound'));
     }
     $report->checkIsEnabled();
     return $report->render();
 }
Beispiel #3
0
 public function get($idSite, $period, $date, $segment = false, $columns = false)
 {
     Piwik::checkUserHasViewAccess($idSite);
     $archive = Archive::build($idSite, $period, $date, $segment);
     $requestedColumns = Piwik::getArrayFromApiParameter($columns);
     $report = Report::factory("VisitsSummary", "get");
     $columns = $report->getMetricsRequiredForReport($this->getCoreColumns($period), $requestedColumns);
     $dataTable = $archive->getDataTableFromNumeric($columns);
     if (!empty($requestedColumns)) {
         $columnsToShow = $requestedColumns ?: $report->getAllMetrics();
         $dataTable->queueFilter('ColumnDelete', array($columnsToRemove = array(), $columnsToShow));
     }
     return $dataTable;
 }
Beispiel #4
0
 public function software()
 {
     $view = new View('@DevicesDetection/software');
     $view->osReport = $this->renderReport('getOsVersions');
     $view->browserReport = $this->renderReport('getBrowsers');
     $view->browserEngineReport = $this->renderReport('getBrowserEngines');
     $isResolutionEnabled = PluginManager::getInstance()->isPluginActivated('Resolution');
     if ($isResolutionEnabled) {
         $view->configurations = $this->renderReport(Report::factory('Resolution', 'getConfiguration'));
     }
     $isDevicePluginsEnabled = PluginManager::getInstance()->isPluginActivated('DevicePlugins');
     if ($isDevicePluginsEnabled) {
         $view->browserPlugins = $this->renderReport(Report::factory('DevicePlugins', 'getPlugin'));
     }
     return $view->render();
 }
Beispiel #5
0
 public function indexSiteSearch()
 {
     $view = new View('@Actions/indexSiteSearch');
     $keyword = Report::factory($this->pluginName, 'getSiteSearchKeywords');
     $noResult = Report::factory($this->pluginName, 'getSiteSearchNoResultKeywords');
     $pageUrls = Report::factory($this->pluginName, 'getPageUrlsFollowingSiteSearch');
     $view->keywords = $keyword->render();
     $view->noResultKeywords = $noResult->render();
     $view->pagesUrlsFollowingSiteSearch = $pageUrls->render();
     $categoryTrackingEnabled = Actions::isCustomVariablesPluginsEnabled();
     if ($categoryTrackingEnabled) {
         $categories = Report::factory($this->pluginName, 'getSiteSearchCategories');
         $view->categories = $categories->render();
     }
     return $view->render();
 }
Beispiel #6
0
 /**
  * Returns the list of metrics (pages, downloads, outlinks)
  *
  * @param int $idSite
  * @param string $period
  * @param string $date
  * @param bool|string $segment
  * @param bool|array $columns
  * @return DataTable
  */
 public function get($idSite, $period, $date, $segment = false, $columns = false)
 {
     Piwik::checkUserHasViewAccess($idSite);
     $report = Report::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', array($newNameMapping));
     $columnsToShow = $requestedColumns ?: $report->getAllMetrics();
     $dataTable->queueFilter('ColumnDelete', array($columnsToRemove = array(), $columnsToShow));
     return $dataTable;
 }
Beispiel #7
0
 public final function __construct($controllerAction, $apiMethodToRequestDataTable, $params = array())
 {
     $templateFile = static::TEMPLATE_FILE;
     if (empty($templateFile)) {
         throw new \Exception('You have not defined a constant named TEMPLATE_FILE in your visualization class.');
     }
     $this->metricsFormatter = new HtmlFormatter();
     parent::__construct($controllerAction, $apiMethodToRequestDataTable, $params);
     $this->report = Report::factory($this->requestConfig->getApiModuleToRequest(), $this->requestConfig->getApiMethodToRequest());
 }
Beispiel #8
0
 public function test_factory_shouldNotFindAReport_IfPluginIsLoadedButNotActivated()
 {
     PluginManager::getInstance()->loadPlugin('ExampleReport');
     $module = 'ExampleReport';
     $action = 'getExampleReport';
     $report = Report::factory($module, $action);
     $this->assertNull($report);
 }
Beispiel #9
0
 /**
  * Return the report object for the given apiAction
  * @param $apiAction
  * @return null|Report
  */
 private static function getReport($apiAction)
 {
     list($module, $action) = explode('.', $apiAction);
     $report = Report::factory($module, $action);
     return $report;
 }
 protected function makeController($module, $action, &$parameters)
 {
     $controllerClassName = $this->getClassNameController($module);
     // TRY TO FIND ACTION IN CONTROLLER
     if (class_exists($controllerClassName)) {
         $class = $this->getClassNameController($module);
         /** @var $controller Controller */
         $controller = new $class();
         $controllerAction = $action;
         if ($controllerAction === false) {
             $controllerAction = $controller->getDefaultAction();
         }
         if (is_callable(array($controller, $controllerAction))) {
             return array($controller, $controllerAction);
         }
         if ($action === false) {
             $this->triggerControllerActionNotFoundError($module, $controllerAction);
         }
     }
     // TRY TO FIND ACTION IN WIDGET
     $widget = Widgets::factory($module, $action);
     if (!empty($widget)) {
         $parameters['widgetModule'] = $module;
         $parameters['widgetMethod'] = $action;
         return array(new CoreHomeController(), 'renderWidget');
     }
     // TRY TO FIND ACTION IN REPORT
     $report = Report::factory($module, $action);
     if (!empty($report)) {
         $parameters['reportModule'] = $module;
         $parameters['reportAction'] = $action;
         return array(new CoreHomeController(), 'renderReportWidget');
     }
     if (!empty($action) && 'menu' === substr($action, 0, 4)) {
         $reportAction = lcfirst(substr($action, 4));
         // menuGetPageUrls => getPageUrls
         $report = Report::factory($module, $reportAction);
         if (!empty($report)) {
             $parameters['reportModule'] = $module;
             $parameters['reportAction'] = $reportAction;
             return array(new CoreHomeController(), 'renderReportMenu');
         }
     }
     $this->triggerControllerActionNotFoundError($module, $action);
 }
Beispiel #11
0
 public function configureViewDataTable(ViewDataTable $view)
 {
     if ($view->requestConfig->getApiModuleToRequest() != 'Events') {
         return;
     }
     // eg. 'Events.getCategory'
     $apiMethod = $view->requestConfig->getApiMethodToRequest();
     $secondaryDimension = $this->getSecondaryDimensionFromRequest();
     $view->config->subtable_controller_action = API::getInstance()->getActionToLoadSubtables($apiMethod, $secondaryDimension);
     if (Common::getRequestVar('pivotBy', false) === false) {
         $view->config->columns_to_display = array('label', 'nb_events', 'sum_event_value');
     }
     $view->config->show_flatten_table = true;
     $view->config->show_table_all_columns = false;
     $view->requestConfig->filter_sort_column = 'nb_events';
     $labelTranslation = $this->getColumnTranslation($apiMethod);
     $view->config->addTranslation('label', $labelTranslation);
     $view->config->addTranslations($this->getMetricTranslations());
     $this->addRelatedReports($view, $secondaryDimension);
     $this->addTooltipEventValue($view);
     $subtableReport = Report::factory('Events', $view->config->subtable_controller_action);
     $view->config->pivot_by_dimension = $subtableReport->getDimension()->getId();
     $view->config->pivot_by_column = 'nb_events';
 }
Beispiel #12
0
 private function checkisValidCallable($module, $action)
 {
     if (!Development::isEnabled()) {
         return;
     }
     $prefix = 'Menu item added in ' . get_class($this) . ' will fail when being selected. ';
     if (!is_string($action)) {
         Development::error($prefix . 'No valid action is specified. Make sure the defined action that should be executed is a string.');
     }
     $reportAction = lcfirst(substr($action, 4));
     if (Report::factory($module, $reportAction)) {
         return;
     }
     $controllerClass = '\\Piwik\\Plugins\\' . $module . '\\Controller';
     if (!Development::methodExists($controllerClass, $action)) {
         Development::error($prefix . 'The defined action "' . $action . '" does not exist in ' . $controllerClass . '". Make sure to define such a method.');
     }
     if (!Development::isCallableMethod($controllerClass, $action)) {
         Development::error($prefix . 'The defined action "' . $action . '" is not callable on "' . $controllerClass . '". Make sure the method is public.');
     }
 }
Beispiel #13
0
 public function test_getSubtableDimension_ShouldReturnCorrectDimensionIfSubtableActionIsDefinedAndCorrect()
 {
     PluginManager::getInstance()->loadPlugins(array('Referrers'));
     $report = Report::factory('Referrers', 'getSearchEngines');
     $subtableDimension = $report->getSubtableDimension();
     $this->assertNotNull($subtableDimension);
     $this->assertInstanceOf("Piwik\\Plugins\\Referrers\\Columns\\Keyword", $subtableDimension);
 }
 private function findCurrentReport()
 {
     return Report::factory($this->apiModule, $this->apiMethod);
 }
Beispiel #15
0
 public function configureViewDataTable(ViewDataTable $view)
 {
     if ($view->requestConfig->getApiModuleToRequest() != 'Events') {
         return;
     }
     // eg. 'Events.getCategory'
     $apiMethod = $view->requestConfig->getApiMethodToRequest();
     $secondaryDimension = $this->getSecondaryDimensionFromRequest();
     $view->config->subtable_controller_action = API::getInstance()->getActionToLoadSubtables($apiMethod, $secondaryDimension);
     if (Common::getRequestVar('pivotBy', false) === false) {
         $view->config->columns_to_display = array('label', 'nb_events', 'sum_event_value');
     }
     $view->config->show_flatten_table = true;
     $view->requestConfig->filter_sort_column = 'nb_events';
     if ($view->isViewDataTableId(AllColumns::ID)) {
         $view->config->filters[] = function (DataTable $table) use($view) {
             $columsToDisplay = array('label');
             $columns = $table->getColumns();
             if (in_array('nb_visits', $columns)) {
                 $columsToDisplay[] = 'nb_visits';
             }
             if (in_array('nb_uniq_visitors', $columns)) {
                 $columsToDisplay[] = 'nb_uniq_visitors';
             }
             $view->config->columns_to_display = array_merge($columsToDisplay, array('nb_events', 'sum_event_value', 'avg_event_value', 'min_event_value', 'max_event_value'));
             if (!in_array($view->requestConfig->filter_sort_column, $view->config->columns_to_display)) {
                 $view->requestConfig->filter_sort_column = 'nb_events';
             }
         };
         $view->config->show_pivot_by_subtable = false;
     }
     $labelTranslation = $this->getColumnTranslation($apiMethod);
     $view->config->addTranslation('label', $labelTranslation);
     $view->config->addTranslations($this->getMetricTranslations());
     $this->addRelatedReports($view, $secondaryDimension);
     $this->addTooltipEventValue($view);
     $subtableReport = Report::factory('Events', $view->config->subtable_controller_action);
     $view->config->pivot_by_dimension = $subtableReport->getDimension()->getId();
     $view->config->pivot_by_column = 'nb_events';
 }
Beispiel #16
0
 public function menuGetContentPieces()
 {
     $report = Report::factory($this->pluginName, 'getContentPieces');
     return View::singleReport($report->getName(), $report->render());
 }
Beispiel #17
0
 /**
  * Returns the default viewDataTable ID to use when determining which visualization to use.
  */
 private static function getDefaultViewTypeForReport($apiAction)
 {
     list($module, $action) = explode('.', $apiAction);
     $report = Report::factory($module, $action);
     if (!empty($report) && $report->isEnabled()) {
         return $report->getDefaultTypeViewDataTable();
     }
     $defaultViewTypes = self::getDefaultTypeViewDataTable();
     return isset($defaultViewTypes[$apiAction]) ? $defaultViewTypes[$apiAction] : false;
 }
Beispiel #18
0
 private function createReportMenuController($module, $action, array &$parameters)
 {
     if (!$this->isReportMenuAction($action)) {
         return null;
     }
     $action = lcfirst(substr($action, 4));
     // menuGetPageUrls => getPageUrls
     $report = Report::factory($module, $action);
     if (!$report) {
         return null;
     }
     $parameters['report'] = $report;
     return array($this->createCoreHomeController(), 'renderReportMenu');
 }
Beispiel #19
0
 /**
  * Convenience method that creates and renders a ViewDataTable for a API method.
  *
  * @param string|\Piwik\Plugin\Report $apiAction The name of the API action (eg, `'getResolution'`) or
  *                                      an instance of an report.
  * @param bool $controllerAction The name of the Controller action name  that is rendering the report. Defaults
  *                               to the `$apiAction`.
  * @param bool $fetch If `true`, the rendered string is returned, if `false` it is `echo`'d.
  * @throws \Exception if `$pluginName` is not an existing plugin or if `$apiAction` is not an
  *                    existing method of the plugin's API.
  * @return string|void See `$fetch`.
  * @api
  */
 protected function renderReport($apiAction, $controllerAction = false)
 {
     if (empty($controllerAction) && is_string($apiAction)) {
         $report = Report::factory($this->pluginName, $apiAction);
         if (!empty($report)) {
             $apiAction = $report;
         }
     }
     if ($apiAction instanceof Report) {
         $this->checkSitePermission();
         $apiAction->checkIsEnabled();
         return $apiAction->render();
     }
     $pluginName = $this->pluginName;
     /** @var Proxy $apiProxy */
     $apiProxy = Proxy::getInstance();
     if (!$apiProxy->isExistingApiAction($pluginName, $apiAction)) {
         throw new \Exception("Invalid action name '{$apiAction}' for '{$pluginName}' plugin.");
     }
     $apiAction = $apiProxy->buildApiActionName($pluginName, $apiAction);
     if ($controllerAction !== false) {
         $controllerAction = $pluginName . '.' . $controllerAction;
     }
     $view = ViewDataTableFactory::build(null, $apiAction, $controllerAction);
     $rendered = $view->render();
     return $rendered;
 }
Beispiel #20
0
 private function setShouldShowPivotBySubtable()
 {
     $report = Report::factory($this->controllerName, $this->controllerAction);
     if (empty($report)) {
         $this->show_pivot_by_subtable = false;
         $this->pivot_by_dimension = false;
     } else {
         $this->show_pivot_by_subtable = PivotByDimension::isPivotingReportBySubtableSupported($report);
         $subtableDimension = $report->getSubtableDimension();
         if (!empty($subtableDimension)) {
             $this->pivot_by_dimension = $subtableDimension->getId();
             $this->pivot_dimension_name = $subtableDimension->getName();
         }
     }
 }
Beispiel #21
0
 /**
  * Constructor. Initializes display and request properties to their default values.
  * Posts the {@hook ViewDataTable.configure} event which plugins can use to configure the
  * way reports are displayed.
  */
 public function __construct($controllerAction, $apiMethodToRequestDataTable, $overrideParams = array())
 {
     list($controllerName, $controllerAction) = explode('.', $controllerAction);
     $this->requestConfig = static::getDefaultRequestConfig();
     $this->config = static::getDefaultConfig();
     $this->config->subtable_controller_action = $controllerAction;
     $this->config->setController($controllerName, $controllerAction);
     $this->request = new ViewDataTableRequest($this->requestConfig);
     $this->requestConfig->idSubtable = Common::getRequestVar('idSubtable', false, 'int');
     $this->config->self_url = Request::getBaseReportUrl($controllerName, $controllerAction);
     $this->requestConfig->apiMethodToRequestDataTable = $apiMethodToRequestDataTable;
     $report = Report::factory($this->requestConfig->getApiModuleToRequest(), $this->requestConfig->getApiMethodToRequest());
     if (!empty($report)) {
         /** @var Report $report */
         $subtable = $report->getActionToLoadSubTables();
         if (!empty($subtable)) {
             $this->config->subtable_controller_action = $subtable;
         }
         $this->config->show_goals = $report->hasGoalMetrics();
         $relatedReports = $report->getRelatedReports();
         if (!empty($relatedReports)) {
             foreach ($relatedReports as $relatedReport) {
                 $widgetTitle = $relatedReport->getWidgetTitle();
                 if ($widgetTitle && Common::getRequestVar('widget', 0, 'int')) {
                     $relatedReportName = $widgetTitle;
                 } else {
                     $relatedReportName = $relatedReport->getName();
                 }
                 $this->config->addRelatedReport($relatedReport->getModule() . '.' . $relatedReport->getAction(), $relatedReportName);
             }
         }
         $metrics = $report->getMetrics();
         if (!empty($metrics)) {
             $this->config->addTranslations($metrics);
         }
         $processedMetrics = $report->getProcessedMetrics();
         if (!empty($processedMetrics)) {
             $this->config->addTranslations($processedMetrics);
         }
         $report->configureView($this);
     }
     /**
      * Triggered during {@link ViewDataTable} construction. Subscribers should customize
      * the view based on the report that is being displayed.
      *
      * Plugins that define their own reports must subscribe to this event in order to
      * specify how the Piwik UI should display the report.
      *
      * **Example**
      *
      *     // event handler
      *     public function configureViewDataTable(ViewDataTable $view)
      *     {
      *         switch ($view->requestConfig->apiMethodToRequestDataTable) {
      *             case 'VisitTime.getVisitInformationPerServerTime':
      *                 $view->config->enable_sort = true;
      *                 $view->requestConfig->filter_limit = 10;
      *                 break;
      *         }
      *     }
      *
      * @param ViewDataTable $view The instance to configure.
      */
     Piwik::postEvent('ViewDataTable.configure', array($this));
     $this->assignRelatedReportsTitle();
     $this->config->show_footer_icons = false == $this->requestConfig->idSubtable;
     // the exclude low population threshold value is sometimes obtained by requesting data.
     // to avoid issuing unecessary requests when display properties are determined by metadata,
     // we allow it to be a closure.
     if (isset($this->requestConfig->filter_excludelowpop_value) && $this->requestConfig->filter_excludelowpop_value instanceof \Closure) {
         $function = $this->requestConfig->filter_excludelowpop_value;
         $this->requestConfig->filter_excludelowpop_value = $function();
     }
     $this->overrideViewPropertiesWithParams($overrideParams);
     $this->overrideViewPropertiesWithQueryParams();
 }
Beispiel #22
0
 /**
  * Similar to {@link get()} but does not return any metrics for new and returning visitors. It won't apply
  * any segment by default. This method is deprecated from the API as it is only there to make the implementation of
  * the actual {@link get()} method easy.
  *
  * @deprecated
  * @internal
  */
 public function getMetrics($idSite, $period, $date, $segment = false, $idGoal = false, $columns = array())
 {
     Piwik::checkUserHasViewAccess($idSite);
     $archive = Archive::build($idSite, $period, $date, $segment);
     // Mapping string idGoal to internal ID
     $idGoal = self::convertSpecialGoalIds($idGoal);
     $isEcommerceGoal = $idGoal === GoalManager::IDGOAL_ORDER || $idGoal === GoalManager::IDGOAL_CART;
     $allMetrics = Goals::getGoalColumns($idGoal);
     $columnsToShow = Piwik::getArrayFromApiParameter($columns);
     $requestedColumns = $columnsToShow;
     $shouldAddAverageOrderRevenue = (in_array('avg_order_revenue', $requestedColumns) || empty($requestedColumns)) && $isEcommerceGoal;
     if ($shouldAddAverageOrderRevenue && !empty($requestedColumns)) {
         $avgOrder = new AverageOrderRevenue();
         $metricsToAdd = $avgOrder->getDependentMetrics();
         $requestedColumns = array_unique(array_merge($requestedColumns, $metricsToAdd));
     }
     $report = Report::factory('Goals', 'getMetrics');
     $columnsToGet = $report->getMetricsRequiredForReport($allMetrics, $requestedColumns);
     $inDbMetricNames = array_map(function ($name) use($idGoal) {
         return $name == 'nb_visits' ? $name : Archiver::getRecordName($name, $idGoal);
     }, $columnsToGet);
     $dataTable = $archive->getDataTableFromNumeric($inDbMetricNames);
     if (count($columnsToGet) > 0) {
         $newNameMapping = array_combine($inDbMetricNames, $columnsToGet);
     } else {
         $newNameMapping = array();
     }
     $dataTable->filter('ReplaceColumnNames', array($newNameMapping));
     // TODO: this should be in Goals/Get.php but it depends on idGoal parameter which isn't always in _GET (ie,
     //       it's not in ProcessedReport.php). more refactoring must be done to report class before this can be
     //       corrected.
     if ($shouldAddAverageOrderRevenue) {
         $dataTable->filter(function (DataTable $table) {
             $extraProcessedMetrics = $table->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME);
             if (empty($extraProcessedMetrics)) {
                 $extraProcessedMetrics = array();
             }
             $extraProcessedMetrics[] = new AverageOrderRevenue();
             $table->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, $extraProcessedMetrics);
         });
     }
     // remove temporary metrics that were not explicitly requested
     if (empty($columnsToShow)) {
         $columnsToShow = $allMetrics;
         $columnsToShow[] = 'conversion_rate';
         if ($isEcommerceGoal) {
             $columnsToShow[] = 'avg_order_revenue';
         }
     }
     $dataTable->queueFilter('ColumnDelete', array($columnsToRemove = array(), $columnsToShow));
     return $dataTable;
 }
Beispiel #23
0
 private function setThisReportMetadata($report)
 {
     list($module, $method) = explode('.', $report);
     $this->thisReport = Report::factory($module, $method);
     if (empty($this->thisReport)) {
         throw new Exception("Unable to find report '{$report}'.");
     }
     $this->subtableDimension = $this->thisReport->getSubtableDimension();
     $thisReportDimension = $this->thisReport->getDimension();
     if ($thisReportDimension !== null) {
         $segments = $thisReportDimension->getSegments();
         $this->thisReportDimensionSegment = reset($segments);
     }
 }
Beispiel #24
0
 public function test_factory_shouldCreateReport_WhenActionNameUsed()
 {
     $this->loadExampleReportPlugin();
     $module = 'ExampleReport';
     $action = 'getExampleReport';
     $report = Report::factory($module, $action);
     $this->assertInstanceOf('Piwik\\Plugins\\ExampleReport\\Reports\\GetExampleReport', $report);
     $this->assertEquals($module, $report->getModule());
     $this->assertEquals($action, $report->getAction());
     // action ucfirst should work as well
     $report = Report::factory($module, ucfirst($action));
     $this->assertInstanceOf('Piwik\\Plugins\\ExampleReport\\Reports\\GetExampleReport', $report);
     $this->assertEquals($module, $report->getModule());
     $this->assertEquals($action, $report->getAction());
 }