Some of the information that is returned by the Metadata API:
  • the dynamically generated list of all API methods via "getReportMetadata"
  • the list of metrics that will be returned by each method, along with their human readable name, via "getDefaultMetrics" and "getDefaultProcessedMetrics"
  • the list of segments metadata supported by all functions that have a 'segment' parameter
  • the (truly magic) method "getProcessedReport" will return a human readable version of any other report, and include the processed metrics such as conversion rate, time on site, etc. which are not directly available in other methods.
  • the method "getSuggestedValuesForSegment" returns top suggested values for a particular segment. It uses the Live.getLastVisitsDetails API to fetch the most recently used values, and will return the most often used values first.
The Metadata API is for example used by the Piwik Mobile App to automatically display all Piwik reports, with translated report & columns names and nicely formatted values. More information on the Metadata API documentation page
Inheritance: extends Piwik\Plugin\API
Example #1
0
 public function test_getBulkRequest_IsAbleToHandleManyDifferentRequests()
 {
     $token = Fixture::getTokenAuth();
     $urls = array("method%3dVisitsSummary.get%26idSite%3d1%26date%3d2015-01-26%26period%3dday", "method%3dVisitsSummary.get%26token_auth%3d{$token}%26idSite%3d1%26date%3d2015-01-26%26period%3dday", "method%3dVisitsSummary.get%26idSite%3d1%26date%3d2015-01-26%26period%3dday", "method%3dVisitsSummary.get%26idSite%3d1%26token_auth%3danonymous%26date%3d2015-01-26%26period%3dday");
     $response = $this->api->getBulkRequest($urls);
     $this->assertResponseIsPermissionError($response[0]);
     $this->assertResponseIsSuccess($response[1]);
     $this->assertSame(0, $response[1]['nb_visits']);
     $this->assertResponseIsPermissionError($response[2]);
     $this->assertResponseIsPermissionError($response[3]);
 }
 /**
  * Constructor.
  */
 public function __construct($idSite = false)
 {
     parent::__construct();
     $this->jsClass = "SegmentSelectorControl";
     $this->cssIdentifier = "segmentEditorPanel";
     $this->cssClass = "piwikTopControl";
     $this->idSite = $idSite ?: Common::getRequestVar('idSite', false, 'int');
     $this->selectedSegment = Common::getRequestVar('segment', false, 'string');
     $segments = APIMetadata::getInstance()->getSegmentsMetadata($this->idSite);
     $segmentsByCategory = $customVariablesSegments = array();
     foreach ($segments as $segment) {
         if ($segment['category'] == Piwik::translate('General_Visit') && ($segment['type'] == 'metric' && $segment['segment'] != 'visitIp')) {
             $metricsLabel = Piwik::translate('General_Metrics');
             $metricsLabel[0] = strtolower($metricsLabel[0]);
             $segment['category'] .= ' (' . $metricsLabel . ')';
         }
         $segmentsByCategory[$segment['category']][] = $segment;
     }
     uksort($segmentsByCategory, array($this, 'sortSegmentCategories'));
     $this->createRealTimeSegmentsIsEnabled = Config::getInstance()->General['enable_create_realtime_segments'];
     $this->segmentsByCategory = $segmentsByCategory;
     $this->nameOfCurrentSegment = '';
     $this->isSegmentNotAppliedBecauseBrowserArchivingIsDisabled = 0;
     $this->availableSegments = API::getInstance()->getAll($this->idSite);
     foreach ($this->availableSegments as &$savedSegment) {
         $savedSegment['name'] = Common::sanitizeInputValue($savedSegment['name']);
         if (!empty($this->selectedSegment) && $this->selectedSegment == $savedSegment['definition']) {
             $this->nameOfCurrentSegment = $savedSegment['name'];
             $this->isSegmentNotAppliedBecauseBrowserArchivingIsDisabled = $this->wouldApplySegment($savedSegment) ? 0 : 1;
         }
     }
     $this->authorizedToCreateSegments = SegmentEditorAPI::getInstance()->isUserCanAddNewSegment($this->idSite);
     $this->isUserAnonymous = Piwik::isUserIsAnonymous();
     $this->segmentTranslations = $this->getTranslations();
 }
 public function getSegmentToTest()
 {
     // Segment matching NONE
     $segments = API::getInstance()->getSegmentsMetadata(self::$fixture->idSite);
     $minimumExpectedSegmentsCount = 55;
     // as of Piwik 1.12
     $this->assertTrue(count($segments) >= $minimumExpectedSegmentsCount);
     $segmentExpression = array();
     $seenVisitorId = false;
     foreach ($segments as $segment) {
         $value = 'campaign';
         if ($segment['segment'] == 'visitorId') {
             $seenVisitorId = true;
             $value = '34c31e04394bdc63';
         }
         if ($segment['segment'] == 'visitEcommerceStatus') {
             $value = 'none';
         }
         $matchNone = $segment['segment'] . '!=' . $value;
         // deviceType != campaign matches ALL visits, but we want to match None
         if ($segment['segment'] == 'deviceType') {
             $matchNone = $segment['segment'] . '==car%20browser';
         }
         $segmentExpression[] = $matchNone;
     }
     $segment = implode(";", $segmentExpression);
     // just checking that this segment was tested (as it has the only visible to admin flag)
     $this->assertTrue($seenVisitorId);
     $this->assertGreaterThan(100, strlen($segment));
     return $segment;
 }
 public function getSelector()
 {
     $view = new View('@SegmentEditor/getSelector');
     $idSite = Common::getRequestVar('idSite');
     $this->setGeneralVariablesView($view);
     $segments = APIMetadata::getInstance()->getSegmentsMetadata($idSite);
     $segmentsByCategory = $customVariablesSegments = array();
     foreach ($segments as $segment) {
         if ($segment['category'] == Piwik::translate('General_Visit') && ($segment['type'] == 'metric' && $segment['segment'] != 'visitIp')) {
             $metricsLabel = Piwik::translate('General_Metrics');
             $metricsLabel[0] = strtolower($metricsLabel[0]);
             $segment['category'] .= ' (' . $metricsLabel . ')';
         }
         $segmentsByCategory[$segment['category']][] = $segment;
     }
     uksort($segmentsByCategory, array($this, 'sortSegmentCategories'));
     $view->segmentsByCategory = $segmentsByCategory;
     $savedSegments = API::getInstance()->getAll($idSite);
     foreach ($savedSegments as &$savedSegment) {
         $savedSegment['name'] = Common::sanitizeInputValue($savedSegment['name']);
     }
     $view->savedSegmentsJson = Common::json_encode($savedSegments);
     $view->authorizedToCreateSegments = !Piwik::isUserIsAnonymous();
     $view->segmentTranslations = Common::json_encode($this->getTranslations());
     $out = $view->render();
     return $out;
 }
 public function getReportMetadata(&$availableReportMetadata, $reportType, $idSite)
 {
     if (self::manageEvent($reportType)) {
         foreach (self::$availableReports as $availableReport) {
             $reportMetadata = APIPlugins::getInstance()->getMetadata($idSite, $availableReport['module'], $availableReport['action']);
             if ($reportMetadata != null) {
                 $reportMetadata = reset($reportMetadata);
                 $availableReportMetadata[] = $reportMetadata;
             }
         }
     }
 }
Example #6
0
 public function getAnotherApiForTesting()
 {
     $apiForTesting = array();
     $segments = \Piwik\Plugins\API\API::getInstance()->getSegmentsMetadata(self::$fixture->idSite);
     foreach ($segments as $segment) {
         if (self::isTravisCI() && $segment['segment'] == 'deviceType') {
             // test started failing after bc19503 and I cannot understand why
             continue;
         }
         $apiForTesting[] = array('VisitsSummary.get', array('idSite' => self::$fixture->idSite, 'date' => date("Y-m-d", strtotime(self::$fixture->dateTime)) . ',today', 'period' => 'range', 'testSuffix' => '_' . $segment['segment'], 'segmentToComplete' => $segment['segment']));
     }
     return $apiForTesting;
 }
Example #7
0
    public function listSegments()
    {
        $segments = API::getInstance()->getSegmentsMetadata($this->idSite);
        $tableDimensions = $tableMetrics = '';
        $customVariables = 0;
        $lastCategory = array();
        foreach ($segments as $segment) {
            // Eg. Event Value is a metric, not in the Visit metric category,
            // we make sure it is displayed along with the Events dimensions
            if ($segment['type'] == 'metric' && $segment['category'] != Piwik::translate('General_Visit')) {
                $segment['type'] = 'dimension';
            }
            $onlyDisplay = array('customVariableName1', 'customVariableName2', 'customVariableValue1', 'customVariableValue2', 'customVariablePageName1', 'customVariablePageValue1');
            $customVariableWillBeDisplayed = in_array($segment['segment'], $onlyDisplay);
            // Don't display more than 4 custom variables name/value rows
            if ($segment['category'] == 'Custom Variables' && !$customVariableWillBeDisplayed) {
                continue;
            }
            $thisCategory = $segment['category'];
            $output = '';
            if (empty($lastCategory[$segment['type']]) || $lastCategory[$segment['type']] != $thisCategory) {
                $output .= '<tr><td class="segmentCategory" colspan="2"><b>' . $thisCategory . '</b></td></tr>';
            }
            $lastCategory[$segment['type']] = $thisCategory;
            $exampleValues = isset($segment['acceptedValues']) ? 'Example values: <code>' . $segment['acceptedValues'] . '</code>' : '';
            $restrictedToAdmin = isset($segment['permission']) ? '<br/>Note: This segment can only be used by an Admin user' : '';
            $output .= '<tr>
							<td class="segmentString">' . $segment['segment'] . '</td>
							<td class="segmentName">' . $segment['name'] . $restrictedToAdmin . '<br/>' . $exampleValues . ' </td>
						</tr>';
            // Show only 2 custom variables and display message for rest
            if ($customVariableWillBeDisplayed) {
                $customVariables++;
                if ($customVariables == count($onlyDisplay)) {
                    $output .= '<tr><td colspan="2"> There are 5 custom variables available, so you can segment across any segment name and value range.
    						<br/>For example, <code>customVariableName1==Type;customVariableValue1==Customer</code>
    						<br/>Returns all visitors that have the Custom Variable "Type" set to "Customer".
    						<br/>Custom Variables of scope "page" can be queried separately. For example, to query the Custom Variable of scope "page",
    						<br/>stored in index 1, you would use the segment <code>customVariablePageName1==ArticleLanguage;customVariablePageValue1==FR</code>
    						</td></tr>';
                }
            }
            if ($segment['type'] == 'dimension') {
                $tableDimensions .= $output;
            } else {
                $tableMetrics .= $output;
            }
        }
        return "\n\t\t<strong>Dimensions</strong>\n\t\t<table>\n\t\t{$tableDimensions}\n\t\t</table>\n\t\t<br/>\n\t\t<strong>Metrics</strong>\n\t\t<table>\n\t\t{$tableMetrics}\n\t\t</table>\n\t\t";
    }
Example #8
0
 public function testAllSizes()
 {
     Piwik::checkUserHasSuperUserAccess();
     $view = new View('@ImageGraph/testAllSizes');
     $this->setGeneralVariablesView($view);
     $period = Common::getRequestVar('period', 'day', 'string');
     $date = Common::getRequestVar('date', 'today', 'string');
     $_GET['token_auth'] = Piwik::getCurrentUserTokenAuth();
     $availableReports = APIPlugins::getInstance()->getReportMetadata($this->idSite, $period, $date);
     $view->availableReports = $availableReports;
     $view->graphTypes = array('');
     $view->graphSizes = array(array(null, null), array(460, 150), array(300, 150), array(240, 150), array(800, 150), array(600, 300, $fontSize = 18, 300, 150));
     return $view->render();
 }
 /**
  * Constructor.
  */
 public function __construct($idSite = false)
 {
     parent::__construct();
     $this->jsClass = "SegmentSelectorControl";
     $this->cssIdentifier = "segmentEditorPanel";
     $this->cssClass = "piwikTopControl borderedControl piwikSelector";
     $this->idSite = $idSite ?: Common::getRequestVar('idSite', false, 'int');
     $this->selectedSegment = Common::getRequestVar('segment', false, 'string');
     $formatter = StaticContainer::get('Piwik\\Plugins\\SegmentEditor\\SegmentFormatter');
     $this->segmentDescription = $formatter->getHumanReadable(Request::getRawSegmentFromRequest(), $this->idSite);
     $this->isAddingSegmentsForAllWebsitesEnabled = SegmentEditor::isAddingSegmentsForAllWebsitesEnabled();
     $segments = APIMetadata::getInstance()->getSegmentsMetadata($this->idSite);
     $visitTitle = Piwik::translate('General_Visit');
     $segmentsByCategory = array();
     foreach ($segments as $segment) {
         if ($segment['category'] == $visitTitle && ($segment['type'] == 'metric' && $segment['segment'] != 'visitIp')) {
             $metricsLabel = Piwik::translate('General_Metrics');
             $metricsLabel[0] = Common::mb_strtolower($metricsLabel[0]);
             $segment['category'] .= ' (' . $metricsLabel . ')';
         }
         $segmentsByCategory[$segment['category']][] = $segment;
     }
     $this->createRealTimeSegmentsIsEnabled = Config::getInstance()->General['enable_create_realtime_segments'];
     $this->segmentsByCategory = $segmentsByCategory;
     $this->nameOfCurrentSegment = '';
     $this->isSegmentNotAppliedBecauseBrowserArchivingIsDisabled = 0;
     $this->availableSegments = API::getInstance()->getAll($this->idSite);
     foreach ($this->availableSegments as &$savedSegment) {
         $savedSegment['name'] = Common::sanitizeInputValue($savedSegment['name']);
         if (!empty($this->selectedSegment) && $this->selectedSegment == $savedSegment['definition']) {
             $this->nameOfCurrentSegment = $savedSegment['name'];
             $this->isSegmentNotAppliedBecauseBrowserArchivingIsDisabled = $this->wouldApplySegment($savedSegment) ? 0 : 1;
         }
     }
     $this->authorizedToCreateSegments = SegmentEditorAPI::getInstance()->isUserCanAddNewSegment($this->idSite);
     $this->isUserAnonymous = Piwik::isUserIsAnonymous();
     $this->segmentTranslations = $this->getTranslations();
     $this->segmentProcessedOnRequest = Rules::isBrowserArchivingAvailableForSegments();
     $this->hideSegmentDefinitionChangeMessage = UsersManagerAPI::getInstance()->getUserPreference(Piwik::getCurrentUserLogin(), 'hideSegmentDefinitionChangeMessage');
 }
Example #10
0
 /**
  * Get a combined report of the *.get API methods.
  */
 public function get($idSite, $period, $date, $segment = false, $columns = false)
 {
     Piwik::checkUserHasViewAccess($idSite);
     $columns = Piwik::getArrayFromApiParameter($columns);
     // build columns map for faster checks later on
     $columnsMap = array();
     foreach ($columns as $column) {
         $columnsMap[$column] = true;
     }
     // find out which columns belong to which plugin
     $columnsByPlugin = array();
     $meta = \Piwik\Plugins\API\API::getInstance()->getReportMetadata($idSite, $period, $date);
     foreach ($meta as $reportMeta) {
         // scan all *.get reports
         if ($reportMeta['action'] == 'get' && !isset($reportMeta['parameters']) && $reportMeta['module'] != 'API' && !empty($reportMeta['metrics'])) {
             $plugin = $reportMeta['module'];
             $allMetrics = array_merge($reportMeta['metrics'], @$reportMeta['processedMetrics'] ?: array());
             foreach ($allMetrics as $column => $columnTranslation) {
                 // a metric from this report has been requested
                 if (isset($columnsMap[$column]) || empty($columnsMap)) {
                     $columnsByPlugin[$plugin][] = $column;
                 }
             }
         }
     }
     krsort($columnsByPlugin);
     $mergedDataTable = false;
     $params = compact('idSite', 'period', 'date', 'segment', 'idGoal');
     foreach ($columnsByPlugin as $plugin => $columns) {
         // load the data
         $className = Request::getClassNameAPI($plugin);
         $params['columns'] = implode(',', $columns);
         $dataTable = Proxy::getInstance()->call($className, 'get', $params);
         $dataTable->filter(function (DataTable $table) {
             $table->clearQueuedFilters();
         });
         // merge reports
         if ($mergedDataTable === false) {
             $mergedDataTable = $dataTable;
         } else {
             $merger = new MergeDataTables();
             $merger->mergeDataTables($mergedDataTable, $dataTable);
         }
     }
     if (!empty($columnsMap) && !empty($mergedDataTable)) {
         $mergedDataTable->queueFilter('ColumnDelete', array(false, array_keys($columnsMap)));
     }
     return $mergedDataTable;
 }
Example #11
0
 private function getReportMetadata()
 {
     $request = $this->request->getRequestArray() + $_GET + $_POST;
     $idSite = Common::getRequestVar('idSite', null, 'string', $request);
     $module = $this->requestConfig->getApiModuleToRequest();
     $action = $this->requestConfig->getApiMethodToRequest();
     $apiParameters = array();
     $idDimension = Common::getRequestVar('idDimension', 0, 'int');
     $idGoal = Common::getRequestVar('idGoal', 0, 'int');
     if ($idDimension > 0) {
         $apiParameters['idDimension'] = $idDimension;
     }
     if ($idGoal > 0) {
         $apiParameters['idGoal'] = $idGoal;
     }
     $metadata = ApiApi::getInstance()->getMetadata($idSite, $module, $action, $apiParameters);
     if (!empty($metadata)) {
         return array_shift($metadata);
     }
     return false;
 }
Example #12
0
 /**
  * Extract the API method for loading subtables from the meta data
  *
  * @throws Exception
  * @return string
  */
 private function getApiMethodForSubtable($request)
 {
     if (!$this->apiMethodForSubtable) {
         if (!empty($request['idSite'])) {
             $idSite = $request['idSite'];
         } else {
             $idSite = 'all';
         }
         $apiParameters = array();
         if (!empty($request['idDimension'])) {
             $apiParameters['idDimension'] = $request['idDimension'];
         }
         if (!empty($request['idGoal'])) {
             $apiParameters['idGoal'] = $request['idGoal'];
         }
         $meta = API::getInstance()->getMetadata($idSite, $this->apiModule, $this->apiMethod, $apiParameters);
         if (empty($meta) && array_key_exists('idGoal', $apiParameters)) {
             unset($apiParameters['idGoal']);
             $meta = API::getInstance()->getMetadata($idSite, $this->apiModule, $this->apiMethod, $apiParameters);
         }
         if (empty($meta)) {
             throw new Exception(sprintf("The DataTable cannot be manipulated: Metadata for report %s.%s could not be found. You can define the metadata in a hook, see example at: http://developer.piwik.org/api-reference/events#apigetreportmetadata", $this->apiModule, $this->apiMethod));
         }
         if (isset($meta[0]['actionToLoadSubTables'])) {
             $this->apiMethodForSubtable = $meta[0]['actionToLoadSubTables'];
         } else {
             $this->apiMethodForSubtable = $this->apiMethod;
         }
     }
     return $this->apiMethodForSubtable;
 }
Example #13
0
 private function getAvailableSegments()
 {
     // segment metadata
     if (empty($this->availableSegments)) {
         $this->availableSegments = API::getInstance()->getSegmentsMetadata($this->idSites, $_hideImplementationData = false);
     }
     return $this->availableSegments;
 }
Example #14
0
 function getVisitEcommerceStatus()
 {
     return APIMetadata::getVisitEcommerceStatusFromId($this->details['visit_goal_buyer']);
 }
Example #15
0
 public function get($idSite, $period, $date, $apiModule, $apiAction, $graphType = false, $outputType = API::GRAPH_OUTPUT_INLINE, $columns = false, $labels = false, $showLegend = true, $width = false, $height = false, $fontSize = API::DEFAULT_FONT_SIZE, $legendFontSize = false, $aliasedGraph = true, $idGoal = false, $colors = false, $textColor = API::DEFAULT_TEXT_COLOR, $backgroundColor = API::DEFAULT_BACKGROUND_COLOR, $gridColor = API::DEFAULT_GRID_COLOR, $idSubtable = false, $legendAppendMetric = true, $segment = false)
 {
     Piwik::checkUserHasViewAccess($idSite);
     // Health check - should we also test for GD2 only?
     if (!SettingsServer::isGdExtensionEnabled()) {
         throw new Exception('Error: To create graphs in Piwik, please enable GD php extension (with Freetype support) in php.ini,
         and restart your web server.');
     }
     $useUnicodeFont = array('am', 'ar', 'el', 'fa', 'fi', 'he', 'ja', 'ka', 'ko', 'te', 'th', 'zh-cn', 'zh-tw');
     $languageLoaded = Translate::getLanguageLoaded();
     $font = self::getFontPath(self::DEFAULT_FONT);
     if (in_array($languageLoaded, $useUnicodeFont)) {
         $unicodeFontPath = self::getFontPath(self::UNICODE_FONT);
         $font = file_exists($unicodeFontPath) ? $unicodeFontPath : $font;
     }
     // save original GET to reset after processing. Important for API-in-API-call
     $savedGET = $_GET;
     try {
         $apiParameters = array();
         if (!empty($idGoal)) {
             $apiParameters = array('idGoal' => $idGoal);
         }
         // Fetch the metadata for given api-action
         $metadata = APIMetadata::getInstance()->getMetadata($idSite, $apiModule, $apiAction, $apiParameters, $languageLoaded, $period, $date, $hideMetricsDoc = false, $showSubtableReports = true);
         if (!$metadata) {
             throw new Exception('Invalid API Module and/or API Action');
         }
         $metadata = $metadata[0];
         $reportHasDimension = !empty($metadata['dimension']);
         $constantRowsCount = !empty($metadata['constantRowsCount']);
         $isMultiplePeriod = Period::isMultiplePeriod($date, $period);
         if (!$reportHasDimension && !$isMultiplePeriod) {
             throw new Exception('The graph cannot be drawn for this combination of \'date\' and \'period\' parameters.');
         }
         if (empty($legendFontSize)) {
             $legendFontSize = (int) $fontSize + self::DEFAULT_LEGEND_FONT_SIZE_OFFSET;
         }
         if (empty($graphType)) {
             if ($isMultiplePeriod) {
                 $graphType = StaticGraph::GRAPH_TYPE_BASIC_LINE;
             } else {
                 if ($constantRowsCount) {
                     $graphType = StaticGraph::GRAPH_TYPE_VERTICAL_BAR;
                 } else {
                     $graphType = StaticGraph::GRAPH_TYPE_HORIZONTAL_BAR;
                 }
             }
             $reportUniqueId = $metadata['uniqueId'];
             if (isset(self::$DEFAULT_GRAPH_TYPE_OVERRIDE[$reportUniqueId][$isMultiplePeriod])) {
                 $graphType = self::$DEFAULT_GRAPH_TYPE_OVERRIDE[$reportUniqueId][$isMultiplePeriod];
             }
         } else {
             $availableGraphTypes = StaticGraph::getAvailableStaticGraphTypes();
             if (!in_array($graphType, $availableGraphTypes)) {
                 throw new Exception(Piwik::translate('General_ExceptionInvalidStaticGraphType', array($graphType, implode(', ', $availableGraphTypes))));
             }
         }
         $width = (int) $width;
         $height = (int) $height;
         if (empty($width)) {
             $width = self::$DEFAULT_PARAMETERS[$graphType][self::WIDTH_KEY];
         }
         if (empty($height)) {
             $height = self::$DEFAULT_PARAMETERS[$graphType][self::HEIGHT_KEY];
         }
         // Cap width and height to a safe amount
         $width = min($width, self::MAX_WIDTH);
         $height = min($height, self::MAX_HEIGHT);
         $reportColumns = array_merge(!empty($metadata['metrics']) ? $metadata['metrics'] : array(), !empty($metadata['processedMetrics']) ? $metadata['processedMetrics'] : array(), !empty($metadata['metricsGoal']) ? $metadata['metricsGoal'] : array(), !empty($metadata['processedMetricsGoal']) ? $metadata['processedMetricsGoal'] : array());
         $ordinateColumns = array();
         if (empty($columns)) {
             $ordinateColumns[] = empty($reportColumns[self::DEFAULT_ORDINATE_METRIC]) ? key($metadata['metrics']) : self::DEFAULT_ORDINATE_METRIC;
         } else {
             $ordinateColumns = explode(',', $columns);
             foreach ($ordinateColumns as $column) {
                 if (empty($reportColumns[$column])) {
                     throw new Exception(Piwik::translate('ImageGraph_ColumnOrdinateMissing', array($column, implode(',', array_keys($reportColumns)))));
                 }
             }
         }
         $ordinateLabels = array();
         foreach ($ordinateColumns as $column) {
             $ordinateLabels[$column] = $reportColumns[$column];
         }
         // sort and truncate filters
         $defaultFilterTruncate = self::$DEFAULT_PARAMETERS[$graphType][self::TRUNCATE_KEY];
         switch ($graphType) {
             case StaticGraph::GRAPH_TYPE_3D_PIE:
             case StaticGraph::GRAPH_TYPE_BASIC_PIE:
                 if (count($ordinateColumns) > 1) {
                     // pChart doesn't support multiple series on pie charts
                     throw new Exception("Pie charts do not currently support multiple series");
                 }
                 $_GET['filter_sort_column'] = reset($ordinateColumns);
                 $this->setFilterTruncate($defaultFilterTruncate);
                 break;
             case StaticGraph::GRAPH_TYPE_VERTICAL_BAR:
             case StaticGraph::GRAPH_TYPE_BASIC_LINE:
                 if (!$isMultiplePeriod && !$constantRowsCount) {
                     $this->setFilterTruncate($defaultFilterTruncate);
                 }
                 break;
         }
         $ordinateLogos = array();
         // row evolutions
         if ($isMultiplePeriod && $reportHasDimension) {
             $plottedMetric = reset($ordinateColumns);
             // when no labels are specified, getRowEvolution returns the top N=filter_limit row evolutions
             // rows are sorted using filter_sort_column (see DataTableGenericFilter for more info)
             if (!$labels) {
                 $savedFilterSortColumnValue = Common::getRequestVar('filter_sort_column', '');
                 $_GET['filter_sort_column'] = $plottedMetric;
                 $savedFilterLimitValue = Common::getRequestVar('filter_limit', -1, 'int');
                 if ($savedFilterLimitValue == -1 || $savedFilterLimitValue > self::MAX_NB_ROW_LABELS) {
                     $_GET['filter_limit'] = self::DEFAULT_NB_ROW_EVOLUTIONS;
                 }
             }
             $processedReport = APIMetadata::getInstance()->getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $plottedMetric, $languageLoaded, $idGoal, $legendAppendMetric, $labelUseAbsoluteUrl = false);
             //@review this test will need to be updated after evaluating the @review comment in API/API.php
             if (!$processedReport) {
                 throw new Exception(Piwik::translate('General_NoDataForGraph'));
             }
             // restoring generic filter parameters
             if (!$labels) {
                 $_GET['filter_sort_column'] = $savedFilterSortColumnValue;
                 if ($savedFilterLimitValue != -1) {
                     $_GET['filter_limit'] = $savedFilterLimitValue;
                 }
             }
             // retrieve metric names & labels
             $metrics = $processedReport['metadata']['metrics'];
             $ordinateLabels = array();
             // getRowEvolution returned more than one label
             if (!array_key_exists($plottedMetric, $metrics)) {
                 $ordinateColumns = array();
                 $i = 0;
                 foreach ($metrics as $metric => $info) {
                     $ordinateColumn = $plottedMetric . '_' . $i++;
                     $ordinateColumns[] = $metric;
                     $ordinateLabels[$ordinateColumn] = $info['name'];
                     if (isset($info['logo'])) {
                         $ordinateLogo = $info['logo'];
                         // @review pChart does not support gifs in graph legends, would it be possible to convert all plugin pictures (cookie.gif, flash.gif, ..) to png files?
                         if (!strstr($ordinateLogo, '.gif')) {
                             $absoluteLogoPath = self::getAbsoluteLogoPath($ordinateLogo);
                             if (file_exists($absoluteLogoPath)) {
                                 $ordinateLogos[$ordinateColumn] = $absoluteLogoPath;
                             }
                         }
                     }
                 }
             } else {
                 $ordinateLabels[$plottedMetric] = $processedReport['label'] . ' (' . $metrics[$plottedMetric]['name'] . ')';
             }
         } else {
             $processedReport = APIMetadata::getInstance()->getProcessedReport($idSite, $period, $date, $apiModule, $apiAction, $segment, $apiParameters = false, $idGoal, $languageLoaded, $showTimer = true, $hideMetricsDoc = false, $idSubtable, $showRawMetrics = false);
         }
         // prepare abscissa and ordinate series
         $abscissaSeries = array();
         $abscissaLogos = array();
         $ordinateSeries = array();
         /** @var \Piwik\DataTable\Simple|\Piwik\DataTable\Map $reportData */
         $reportData = $processedReport['reportData'];
         $hasData = false;
         $hasNonZeroValue = false;
         if (!$isMultiplePeriod) {
             $reportMetadata = $processedReport['reportMetadata']->getRows();
             $i = 0;
             // $reportData instanceof DataTable
             foreach ($reportData->getRows() as $row) {
                 // $row instanceof Row
                 $rowData = $row->getColumns();
                 // Associative Array
                 $abscissaSeries[] = Common::unsanitizeInputValue($rowData['label']);
                 foreach ($ordinateColumns as $column) {
                     $parsedOrdinateValue = $this->parseOrdinateValue($rowData[$column]);
                     $hasData = true;
                     if ($parsedOrdinateValue != 0) {
                         $hasNonZeroValue = true;
                     }
                     $ordinateSeries[$column][] = $parsedOrdinateValue;
                 }
                 if (isset($reportMetadata[$i])) {
                     $rowMetadata = $reportMetadata[$i]->getColumns();
                     if (isset($rowMetadata['logo'])) {
                         $absoluteLogoPath = self::getAbsoluteLogoPath($rowMetadata['logo']);
                         if (file_exists($absoluteLogoPath)) {
                             $abscissaLogos[$i] = $absoluteLogoPath;
                         }
                     }
                 }
                 $i++;
             }
         } else {
             // $periodsData instanceof Simple[]
             $periodsData = array_values($reportData->getDataTables());
             $periodsCount = count($periodsData);
             for ($i = 0; $i < $periodsCount; $i++) {
                 // $periodsData[$i] instanceof Simple
                 // $rows instanceof Row[]
                 if (empty($periodsData[$i])) {
                     continue;
                 }
                 $rows = $periodsData[$i]->getRows();
                 if (array_key_exists(0, $rows)) {
                     $rowData = $rows[0]->getColumns();
                     // associative Array
                     foreach ($ordinateColumns as $column) {
                         $ordinateValue = $rowData[$column];
                         $parsedOrdinateValue = $this->parseOrdinateValue($ordinateValue);
                         $hasData = true;
                         if (!empty($parsedOrdinateValue)) {
                             $hasNonZeroValue = true;
                         }
                         $ordinateSeries[$column][] = $parsedOrdinateValue;
                     }
                 } else {
                     foreach ($ordinateColumns as $column) {
                         $ordinateSeries[$column][] = 0;
                     }
                 }
                 $rowId = $periodsData[$i]->getMetadata(DataTableFactory::TABLE_METADATA_PERIOD_INDEX)->getLocalizedShortString();
                 $abscissaSeries[] = Common::unsanitizeInputValue($rowId);
             }
         }
         if (!$hasData || !$hasNonZeroValue) {
             throw new Exception(Piwik::translate('General_NoDataForGraph'));
         }
         //Setup the graph
         $graph = StaticGraph::factory($graphType);
         $graph->setWidth($width);
         $graph->setHeight($height);
         $graph->setFont($font);
         $graph->setFontSize($fontSize);
         $graph->setLegendFontSize($legendFontSize);
         $graph->setOrdinateLabels($ordinateLabels);
         $graph->setShowLegend($showLegend);
         $graph->setAliasedGraph($aliasedGraph);
         $graph->setAbscissaSeries($abscissaSeries);
         $graph->setAbscissaLogos($abscissaLogos);
         $graph->setOrdinateSeries($ordinateSeries);
         $graph->setOrdinateLogos($ordinateLogos);
         $graph->setColors(!empty($colors) ? explode(',', $colors) : array());
         $graph->setTextColor($textColor);
         $graph->setBackgroundColor($backgroundColor);
         $graph->setGridColor($gridColor);
         // when requested period is day, x-axis unit is time and all date labels can not be displayed
         // within requested width, force labels to be skipped every 6 days to delimit weeks
         if ($period == 'day' && $isMultiplePeriod) {
             $graph->setForceSkippedLabels(6);
         }
         // render graph
         $graph->renderGraph();
     } catch (\Exception $e) {
         $graph = new \Piwik\Plugins\ImageGraph\StaticGraph\Exception();
         $graph->setWidth($width);
         $graph->setHeight($height);
         $graph->setFont($font);
         $graph->setFontSize($fontSize);
         $graph->setBackgroundColor($backgroundColor);
         $graph->setTextColor($textColor);
         $graph->setException($e);
         $graph->renderGraph();
     }
     // restoring get parameters
     $_GET = $savedGET;
     switch ($outputType) {
         case self::GRAPH_OUTPUT_FILE:
             if ($idGoal != '') {
                 $idGoal = '_' . $idGoal;
             }
             $fileName = self::$DEFAULT_PARAMETERS[$graphType][self::FILENAME_KEY] . '_' . $apiModule . '_' . $apiAction . $idGoal . ' ' . str_replace(',', '-', $date) . ' ' . $idSite . '.png';
             $fileName = str_replace(array(' ', '/'), '_', $fileName);
             if (!Filesystem::isValidFilename($fileName)) {
                 throw new Exception('Error: Image graph filename ' . $fileName . ' is not valid.');
             }
             return $graph->sendToDisk($fileName);
         case self::GRAPH_OUTPUT_PHP:
             return $graph->getRenderedImage();
         case self::GRAPH_OUTPUT_INLINE:
         default:
             $graph->sendToBrowser();
             exit;
     }
 }
 /**
  * For a given API report, returns a simpler version
  * of the metadata (will return only the metrics and the dimension name)
  * @param $idSite
  * @param $period
  * @param $date
  * @param $apiModule
  * @param $apiAction
  * @param $language
  * @param $idGoal
  * @throws Exception
  * @return array
  */
 private function getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal = false)
 {
     $apiParameters = array();
     if (!empty($idGoal) && $idGoal > 0) {
         $apiParameters = array('idGoal' => $idGoal);
     }
     $reportMetadata = API::getInstance()->getMetadata($idSite, $apiModule, $apiAction, $apiParameters, $language, $period, $date, $hideMetricsDoc = false, $showSubtableReports = true);
     if (empty($reportMetadata)) {
         throw new Exception("Requested report {$apiModule}.{$apiAction} for Website id={$idSite} " . "not found in the list of available reports. \n");
     }
     $reportMetadata = reset($reportMetadata);
     $metrics = $reportMetadata['metrics'];
     if (isset($reportMetadata['processedMetrics']) && is_array($reportMetadata['processedMetrics'])) {
         $metrics = $metrics + $reportMetadata['processedMetrics'];
     }
     $dimension = $reportMetadata['dimension'];
     return compact('metrics', 'dimension');
 }
Example #17
0
 /**
  * Assigns a set of generally useful variables to a {@link Piwik\View} instance.
  * 
  * The following variables assigned:
  * 
  * **enableMeasurePiwikForSiteId** - The value of the `[Debug] enable_measure_piwik_usage_in_idsite`
  *                                     INI config option.
  * **isSuperUser** - True if the current user is the Super User, false if otherwise.
  * **hasSomeAdminAccess** - True if the current user has admin access to at least one site,
  *                          false if otherwise.
  * **isCustomLogo** - The value of the `branding_use_custom_logo` option.
  * **logoHeader** - The header logo URL to use.
  * **logoLarge** - The large logo URL to use.
  * **logoSVG** - The SVG logo URL to use.
  * **hasSVGLogo** - True if there is a SVG logo, false if otherwise.
  * **enableFrames** - The value of the `[General] enable_framed_pages` INI config option. If
  *                    true, {@link Piwik\View::setXFrameOptions()} is called on the view.
  * 
  * Also calls {@link setHostValidationVariablesView()}.
  *
  * @param View $view
  * @api
  */
 protected function setBasicVariablesView($view)
 {
     $view->clientSideConfig = PiwikConfig::getInstance()->getClientSideOptions();
     $view->enableMeasurePiwikForSiteId = PiwikConfig::getInstance()->Debug['enable_measure_piwik_usage_in_idsite'];
     $view->isSuperUser = Access::getInstance()->hasSuperUserAccess();
     $view->hasSomeAdminAccess = Piwik::isUserHasSomeAdminAccess();
     $view->hasSomeViewAccess = Piwik::isUserHasSomeViewAccess();
     $view->isUserIsAnonymous = Piwik::isUserIsAnonymous();
     $view->hasSuperUserAccess = Piwik::hasUserSuperUserAccess();
     $this->addCustomLogoInfo($view);
     $view->logoHeader = \Piwik\Plugins\API\API::getInstance()->getHeaderLogoUrl();
     $view->logoLarge = \Piwik\Plugins\API\API::getInstance()->getLogoUrl();
     $view->logoSVG = \Piwik\Plugins\API\API::getInstance()->getSVGLogoUrl();
     $view->hasSVGLogo = \Piwik\Plugins\API\API::getInstance()->hasSVGLogo();
     $view->superUserEmails = implode(',', Piwik::getAllSuperUserAccessEmailAddresses());
     $general = PiwikConfig::getInstance()->General;
     $view->enableFrames = $general['enable_framed_pages'] || isset($general['enable_framed_logins']) && $general['enable_framed_logins'];
     if (!$view->enableFrames) {
         $view->setXFrameOptions('sameorigin');
     }
     self::setHostValidationVariablesView($view);
 }
Example #18
0
 public function renderFrontPage($reportTitle, $prettyDate, $description, $reportMetadata, $segment)
 {
     $reportTitle = $this->formatText($reportTitle);
     $dateRange = $this->formatText(Piwik::translate('General_DateRange') . " " . $prettyDate);
     // footer
     $this->TCPDF->SetFooterFont(array($this->reportFont, $this->reportFontStyle, $this->reportSimpleFontSize));
     $this->TCPDF->SetFooterContent($reportTitle . " | " . $dateRange . " | ");
     // add first page
     $this->TCPDF->setPrintHeader(false);
     $this->TCPDF->AddPage(self::PORTRAIT);
     $this->TCPDF->AddFont($this->reportFont, '', '', false);
     $this->TCPDF->SetFont($this->reportFont, $this->reportFontStyle, $this->reportSimpleFontSize);
     $this->TCPDF->Bookmark(Piwik::translate('ScheduledReports_FrontPage'));
     // logo
     $this->TCPDF->Image(API::getInstance()->getLogoUrl(true), $this->logoImagePosition[0], $this->logoImagePosition[1], 180 / ($factor = 2), 0, $type = '', $link = '', $align = '', $resize = false, $dpi = 300);
     $this->TCPDF->Ln(8);
     // report title
     $this->TCPDF->SetFont($this->reportFont, '', $this->reportHeaderFontSize + 5);
     $this->TCPDF->SetTextColor($this->headerTextColor[0], $this->headerTextColor[1], $this->headerTextColor[2]);
     $this->TCPDF->Cell(40, 210, $reportTitle);
     $this->TCPDF->Ln(8 * 4);
     // date and period
     $this->TCPDF->SetFont($this->reportFont, '', $this->reportHeaderFontSize);
     $this->TCPDF->SetTextColor($this->reportTextColor[0], $this->reportTextColor[1], $this->reportTextColor[2]);
     $this->TCPDF->Cell(40, 210, $dateRange);
     $this->TCPDF->Ln(8 * 20);
     // description
     $this->TCPDF->Write(1, $this->formatText($description));
     // segment
     if ($segment != null) {
         $this->TCPDF->Ln();
         $this->TCPDF->Ln();
         $this->TCPDF->SetFont($this->reportFont, '', $this->reportHeaderFontSize - 2);
         $this->TCPDF->SetTextColor($this->headerTextColor[0], $this->headerTextColor[1], $this->headerTextColor[2]);
         $this->TCPDF->Write(1, $this->formatText(Piwik::translate('ScheduledReports_CustomVisitorSegment') . ' ' . $segment['name']));
     }
     $this->TCPDF->Ln(8);
     $this->TCPDF->SetFont($this->reportFont, '', $this->reportHeaderFontSize);
     $this->TCPDF->Ln();
 }
Example #19
0
 /**
  * Get a combined report of the *.get API methods.
  */
 public function get($idSite, $period, $date, $segment = false, $columns = false)
 {
     $columns = Piwik::getArrayFromApiParameter($columns);
     // build columns map for faster checks later on
     $columnsMap = array();
     foreach ($columns as $column) {
         $columnsMap[$column] = true;
     }
     // find out which columns belong to which plugin
     $columnsByPlugin = array();
     $meta = \Piwik\Plugins\API\API::getInstance()->getReportMetadata($idSite, $period, $date);
     foreach ($meta as $reportMeta) {
         // scan all *.get reports
         if ($reportMeta['action'] == 'get' && !isset($reportMeta['parameters']) && $reportMeta['module'] != 'API' && !empty($reportMeta['metrics'])) {
             $plugin = $reportMeta['module'];
             foreach ($reportMeta['metrics'] as $column => $columnTranslation) {
                 // a metric from this report has been requested
                 if (isset($columnsMap[$column]) || empty($columnsMap)) {
                     $columnsByPlugin[$plugin][] = $column;
                 }
             }
         }
     }
     krsort($columnsByPlugin);
     $mergedDataTable = false;
     $params = compact('idSite', 'period', 'date', 'segment', 'idGoal');
     foreach ($columnsByPlugin as $plugin => $columns) {
         // load the data
         $className = Request::getClassNameAPI($plugin);
         $params['columns'] = implode(',', $columns);
         $dataTable = Proxy::getInstance()->call($className, 'get', $params);
         // make sure the table has all columns
         $array = $dataTable instanceof DataTable\Map ? $dataTable->getDataTables() : array($dataTable);
         foreach ($array as $table) {
             // we don't support idSites=all&date=DATE1,DATE2
             if ($table instanceof DataTable) {
                 $firstRow = $table->getFirstRow();
                 if (!$firstRow) {
                     $firstRow = new Row();
                     $table->addRow($firstRow);
                 }
                 foreach ($columns as $column) {
                     if ($firstRow->getColumn($column) === false) {
                         $firstRow->setColumn($column, 0);
                     }
                 }
             }
         }
         // merge reports
         if ($mergedDataTable === false) {
             $mergedDataTable = $dataTable;
         } else {
             $this->mergeDataTables($mergedDataTable, $dataTable);
         }
     }
     return $mergedDataTable;
 }
 private function getReportMetadata()
 {
     if (!empty(static::$reportMetadata)) {
         return static::$reportMetadata;
     }
     static::$reportMetadata = API::getInstance()->getReportMetadata();
     return static::$reportMetadata;
 }
Example #21
0
 private function assignCommonParameters(View $view)
 {
     $view->assign("reportFontFamily", ReportRenderer::DEFAULT_REPORT_FONT_FAMILY);
     $view->assign("reportTitleTextColor", ReportRenderer::REPORT_TITLE_TEXT_COLOR);
     $view->assign("reportTitleTextSize", self::REPORT_TITLE_TEXT_SIZE);
     $view->assign("reportTextColor", ReportRenderer::REPORT_TEXT_COLOR);
     $view->assign("tableHeaderBgColor", ReportRenderer::TABLE_HEADER_BG_COLOR);
     $view->assign("tableHeaderTextColor", ReportRenderer::TABLE_HEADER_TEXT_COLOR);
     $view->assign("tableCellBorderColor", ReportRenderer::TABLE_CELL_BORDER_COLOR);
     $view->assign("tableBgColor", ReportRenderer::TABLE_BG_COLOR);
     $view->assign("reportTableHeaderTextWeight", self::TABLE_HEADER_TEXT_WEIGHT);
     $view->assign("reportTableHeaderTextSize", self::REPORT_TABLE_HEADER_TEXT_SIZE);
     $view->assign("reportTableHeaderTextTransform", ReportRenderer::TABLE_HEADER_TEXT_TRANSFORM);
     $view->assign("reportTableRowTextSize", self::REPORT_TABLE_ROW_TEXT_SIZE);
     $view->assign("reportBackToTopTextSize", self::REPORT_BACK_TO_TOP_TEXT_SIZE);
     $view->assign("currentPath", SettingsPiwik::getPiwikUrl());
     $view->assign("logoHeader", API::getInstance()->getHeaderLogoUrl());
 }
Example #22
0
 /** Load documentation from the API */
 private function loadDocumentation()
 {
     $this->metrics_documentation = array();
     $idSite = Common::getRequestVar('idSite', 0, 'int');
     if ($idSite < 1) {
         return;
     }
     $apiParameters = array();
     $idDimension = Common::getRequestVar('idDimension', 0, 'int');
     $idGoal = Common::getRequestVar('idGoal', 0, 'int');
     if ($idDimension > 0) {
         $apiParameters['idDimension'] = $idDimension;
     }
     if ($idGoal > 0) {
         $apiParameters['idGoal'] = $idGoal;
     }
     $report = API::getInstance()->getMetadata($idSite, $this->controllerName, $this->controllerAction, $apiParameters);
     if (empty($report)) {
         return;
     }
     $report = $report[0];
     if (isset($report['metricsDocumentation'])) {
         $this->metrics_documentation = $report['metricsDocumentation'];
     }
     if (isset($report['documentation'])) {
         $this->documentation = $report['documentation'];
     }
 }
Example #23
0
 private function getReportMetadata()
 {
     $request = $this->request->getRequestArray() + $_GET + $_POST;
     $idSite = Common::getRequestVar('idSite', null, 'string', $request);
     $module = $this->requestConfig->getApiModuleToRequest();
     $action = $this->requestConfig->getApiMethodToRequest();
     $metadata = ApiApi::getInstance()->getMetadata($idSite, $module, $action);
     if (!empty($metadata)) {
         return array_shift($metadata);
     }
     return false;
 }
 public static function getSegmentsMetadata($idSite)
 {
     // Refresh cache for CustomVariables\Model
     Cache::clearCacheGeneral();
     \Piwik\Plugins\CustomVariables\Model::install();
     // Segment matching NONE
     $segments = \Piwik\Plugins\API\API::getInstance()->getSegmentsMetadata($idSite);
     return $segments;
 }
Example #25
0
 public function getReportMetadata(&$reportMetadata, $reportType, $idSite)
 {
     if (!self::manageEvent($reportType)) {
         return;
     }
     $availableReportMetadata = \Piwik\Plugins\API\API::getInstance()->getReportMetadata($idSite);
     $filteredReportMetadata = array();
     foreach ($availableReportMetadata as $reportMetadata) {
         // removing reports from the API category and MultiSites.getOne
         if ($reportMetadata['category'] == 'API' || $reportMetadata['category'] == Piwik::translate('General_MultiSitesSummary') && $reportMetadata['name'] == Piwik::translate('General_SingleWebsitesDashboard')) {
             continue;
         }
         $filteredReportMetadata[] = $reportMetadata;
     }
     $reportMetadata = $filteredReportMetadata;
 }
Example #26
0
 /**
  * Generates a report file.
  *
  * @param int $idReport ID of the report to generate.
  * @param string $date YYYY-MM-DD
  * @param bool|false|string $language If not passed, will use default language.
  * @param bool|false|int $outputType 1 = download report, 2 = save report to disk, 3 = output report in browser, 4 = return report content to caller, defaults to download
  * @param bool|false|string $period Defaults to 'day'. If not specified, will default to the report's period set when creating the report
  * @param bool|false|string $reportFormat 'pdf', 'html' or any other format provided via the ScheduledReports.getReportFormats hook
  * @param bool|false|array $parameters array of parameters
  * @return array|void
  */
 public function generateReport($idReport, $date, $language = false, $outputType = false, $period = false, $reportFormat = false, $parameters = false)
 {
     Piwik::checkUserIsNotAnonymous();
     // load specified language
     if (empty($language)) {
         $language = Translate::getLanguageDefault();
     }
     Translate::reloadLanguage($language);
     $reports = $this->getReports($idSite = false, $_period = false, $idReport);
     $report = reset($reports);
     $idSite = $report['idsite'];
     $login = $report['login'];
     $reportType = $report['type'];
     $this->checkUserHasViewPermission($login, $idSite);
     // override report period
     if (empty($period)) {
         $period = $report['period'];
     }
     // override report format
     if (!empty($reportFormat)) {
         self::validateReportFormat($reportType, $reportFormat);
         $report['format'] = $reportFormat;
     } else {
         $reportFormat = $report['format'];
     }
     // override and/or validate report parameters
     $report['parameters'] = Common::json_decode(self::validateReportParameters($reportType, empty($parameters) ? $report['parameters'] : $parameters), true);
     // available reports
     $availableReportMetadata = \Piwik\Plugins\API\API::getInstance()->getReportMetadata($idSite);
     // we need to lookup which reports metadata are registered in this report
     $reportMetadata = array();
     foreach ($availableReportMetadata as $metadata) {
         if (in_array($metadata['uniqueId'], $report['reports'])) {
             $reportMetadata[] = $metadata;
         }
     }
     // the report will be rendered with the first 23 rows and will aggregate other rows in a summary row
     // 23 rows table fits in one portrait page
     $initialFilterTruncate = Common::getRequestVar('filter_truncate', false);
     $_GET['filter_truncate'] = self::REPORT_TRUNCATE;
     $prettyDate = null;
     $processedReports = array();
     $segment = self::getSegment($report['idsegment']);
     foreach ($reportMetadata as $action) {
         $apiModule = $action['module'];
         $apiAction = $action['action'];
         $apiParameters = array();
         if (isset($action['parameters'])) {
             $apiParameters = $action['parameters'];
         }
         $mustRestoreGET = false;
         // all Websites dashboard should not be truncated in the report
         if ($apiModule == 'MultiSites') {
             $mustRestoreGET = $_GET;
             $_GET['enhanced'] = true;
             if ($apiAction == 'getAll') {
                 $_GET['filter_truncate'] = false;
                 // when a view/admin user created a report, workaround the fact that "Super User"
                 // is enforced in Scheduled tasks, and ensure Multisites.getAll only return the websites that this user can access
                 $userLogin = $report['login'];
                 if (!empty($userLogin) && !Piwik::hasTheUserSuperUserAccess($userLogin)) {
                     $_GET['_restrictSitesToLogin'] = $userLogin;
                 }
             }
         }
         $processedReport = \Piwik\Plugins\API\API::getInstance()->getProcessedReport($idSite, $period, $date, $apiModule, $apiAction, $segment != null ? urlencode($segment['definition']) : false, $apiParameters, $idGoal = false, $language);
         $processedReport['segment'] = $segment;
         // TODO add static method getPrettyDate($period, $date) in Period
         $prettyDate = $processedReport['prettyDate'];
         if ($mustRestoreGET) {
             $_GET = $mustRestoreGET;
         }
         $processedReports[] = $processedReport;
     }
     // restore filter truncate parameter value
     if ($initialFilterTruncate !== false) {
         $_GET['filter_truncate'] = $initialFilterTruncate;
     }
     /**
      * Triggered when generating the content of scheduled reports.
      *
      * This event can be used to modify the report data or report metadata of one or more reports
      * in a scheduled report, before the scheduled report is rendered and delivered.
      * 
      * TODO: list data available in $report or make it a new class that can be documented (same for
      *       all other events that use a $report)
      * 
      * @param array &$processedReports The list of processed reports in the scheduled
      *                                 report. Entries includes report data and metadata for each report.
      * @param string $reportType A string ID describing how the scheduled report will be sent, eg,
      *                           `'sms'` or `'email'`.
      * @param string $outputType The output format of the report, eg, `'html'`, `'pdf'`, etc.
      * @param array $report An array describing the scheduled report that is being
      *                      generated.
      */
     Piwik::postEvent(self::PROCESS_REPORTS_EVENT, array(&$processedReports, $reportType, $outputType, $report));
     $reportRenderer = null;
     /**
      * Triggered when obtaining a renderer instance based on the scheduled report output format.
      * 
      * Plugins that provide new scheduled report output formats should use this event to
      * handle their new report formats.
      * 
      * @param ReportRenderer &$reportRenderer This variable should be set to an instance that
      *                                        extends {@link Piwik\ReportRenderer} by one of the event
      *                                        subscribers.
      * @param string $reportType A string ID describing how the report is sent, eg,
      *                           `'sms'` or `'email'`.
      * @param string $outputType The output format of the report, eg, `'html'`, `'pdf'`, etc.
      * @param array $report An array describing the scheduled report that is being
      *                      generated.
      */
     Piwik::postEvent(self::GET_RENDERER_INSTANCE_EVENT, array(&$reportRenderer, $reportType, $outputType, $report));
     if (is_null($reportRenderer)) {
         throw new Exception("A report renderer was not supplied in the event " . self::GET_RENDERER_INSTANCE_EVENT);
     }
     // init report renderer
     $reportRenderer->setLocale($language);
     // render report
     $description = str_replace(array("\r", "\n"), ' ', $report['description']);
     list($reportSubject, $reportTitle) = self::getReportSubjectAndReportTitle(Site::getNameFor($idSite), $report['reports']);
     $filename = "{$reportTitle} - {$prettyDate} - {$description}";
     $reportRenderer->renderFrontPage($reportTitle, $prettyDate, $description, $reportMetadata, $segment);
     array_walk($processedReports, array($reportRenderer, 'renderReport'));
     switch ($outputType) {
         case self::OUTPUT_SAVE_ON_DISK:
             $outputFilename = strtoupper($reportFormat) . ' ' . ucfirst($reportType) . ' Report - ' . $idReport . '.' . $date . '.' . $idSite . '.' . $language;
             $outputFilename = $reportRenderer->sendToDisk($outputFilename);
             $additionalFiles = $this->getAttachments($reportRenderer, $report, $processedReports, $prettyDate);
             return array($outputFilename, $prettyDate, $reportSubject, $reportTitle, $additionalFiles);
             break;
         case self::OUTPUT_INLINE:
             $reportRenderer->sendToBrowserInline($filename);
             break;
         case self::OUTPUT_RETURN:
             return $reportRenderer->getRenderedReport();
             break;
         default:
         case self::OUTPUT_DOWNLOAD:
             $reportRenderer->sendToBrowserDownload($filename);
             break;
     }
 }
Example #27
0
 protected function getCleanedExpression($expression)
 {
     if (empty($this->availableSegments)) {
         $this->availableSegments = API::getInstance()->getSegmentsMetadata($this->idSites, $_hideImplementationData = false);
     }
     $name = $expression[0];
     $matchType = $expression[1];
     $value = $expression[2];
     $sqlName = '';
     foreach ($this->availableSegments as $segment) {
         if ($segment['segment'] != $name) {
             continue;
         }
         $sqlName = $segment['sqlSegment'];
         // check permission
         if (isset($segment['permission']) && $segment['permission'] != 1) {
             throw new NoAccessException("You do not have enough permission to access the segment " . $name);
         }
         if ($matchType != SegmentExpression::MATCH_IS_NOT_NULL_NOR_EMPTY && $matchType != SegmentExpression::MATCH_IS_NULL_OR_EMPTY) {
             if (isset($segment['sqlFilterValue'])) {
                 $value = call_user_func($segment['sqlFilterValue'], $value);
             }
             // apply presentation filter
             if (isset($segment['sqlFilter'])) {
                 $value = call_user_func($segment['sqlFilter'], $value, $segment['sqlSegment'], $matchType, $name);
                 if (is_null($value)) {
                     // null is returned in TableLogAction::getIdActionFromSegment()
                     return array(null, $matchType, null);
                 }
                 // sqlFilter-callbacks might return arrays for more complex cases
                 // e.g. see TableLogAction::getIdActionFromSegment()
                 if (is_array($value) && isset($value['SQL'])) {
                     // Special case: returned value is a sub sql expression!
                     $matchType = SegmentExpression::MATCH_ACTIONS_CONTAINS;
                 }
             }
         }
         break;
     }
     if (empty($sqlName)) {
         throw new Exception("Segment '{$name}' is not a supported segment.");
     }
     return array($sqlName, $matchType, $value);
 }
Example #28
0
 /**
  * @return array|null
  */
 protected function getApiMetaData()
 {
     if ($this->apiMetaData === null) {
         list($apiModule, $apiAction) = explode('.', $this->apiMethod);
         if (!$apiModule || !$apiAction) {
             $this->apiMetaData = false;
         }
         $api = \Piwik\Plugins\API\API::getInstance();
         $meta = $api->getMetadata($this->idSite, $apiModule, $apiAction);
         if (is_array($meta[0])) {
             $meta = $meta[0];
         }
         $this->apiMetaData =& $meta;
     }
     return $this->apiMetaData;
 }
 /**
  * Extract the API method for loading subtables from the meta data
  *
  * @throws Exception
  * @return string
  */
 private function getApiMethodForSubtable()
 {
     if (!$this->apiMethodForSubtable) {
         $meta = API::getInstance()->getMetadata('all', $this->apiModule, $this->apiMethod);
         if (empty($meta)) {
             throw new Exception(sprintf("The DataTable cannot be manipulated: Metadata for report %s.%s could not be found. You can define the metadata in a hook, see example at: http://developer.piwik.org/api-reference/events#apigetreportmetadata", $this->apiModule, $this->apiMethod));
         }
         if (isset($meta[0]['actionToLoadSubTables'])) {
             $this->apiMethodForSubtable = $meta[0]['actionToLoadSubTables'];
         } else {
             $this->apiMethodForSubtable = $this->apiMethod;
         }
     }
     return $this->apiMethodForSubtable;
 }
Example #30
0
 /** Load documentation from the API */
 private function loadDocumentation()
 {
     $this->metrics_documentation = array();
     $report = API::getInstance()->getMetadata(0, $this->controllerName, $this->controllerAction);
     $report = $report[0];
     if (isset($report['metricsDocumentation'])) {
         $this->metrics_documentation = $report['metricsDocumentation'];
     }
     if (isset($report['documentation'])) {
         $this->documentation = $report['documentation'];
     }
 }