Ejemplo n.º 1
0
 /**
  * Generates a report file.
  *
  * @param int $idReport ID of the report to generate. If idReport=0 it will generate a report containing all reports
  * for the specified period & date
  * @param string $date YYYY-MM-DD
  * @param int|false $idSite
  * @param string|false $language If not passed, will use default language.
  * @param int|false $outputType 1 = download report, 2 = save report to disk, defaults to download
  * @param string|false $period Defaults to 'day'. If not specified, will default to the report's period set when creating the report
  * @param string $reportFormat pdf, html
  * @param int|false $aggregateReportsFormat 1 = display only tables, 2 = display only graphs, 3 = display both
  */
 public function generateReport($idReport, $date, $idSite = false, $language = false, $outputType = false, $period = false, $reportFormat = false, $aggregateReportsFormat = false)
 {
     Piwik::checkUserIsNotAnonymous();
     // Load specified language
     if (empty($language)) {
         $language = Piwik_Translate::getInstance()->getLanguageDefault();
     }
     Piwik_Translate::getInstance()->reloadLanguage($language);
     // Available reports
     $reportMetadata = Piwik_API_API::getInstance()->getReportMetadata($idSite);
     // Test template: include all reports
     if ($idReport == 0) {
         if (empty($period)) {
             $period = 'day';
         }
         if (empty($reportFormat)) {
             $reportFormat = Piwik_PDFReports::DEFAULT_FORMAT;
         }
         if (empty($aggregateReportsFormat)) {
             $aggregateReportsFormat = Piwik_PDFReports::DEFAULT_AGGREGATE_REPORTS_FORMAT;
         }
         $reports = array();
         foreach ($reportMetadata as $report) {
             if ($report['category'] != 'API') {
                 $reports[] = $report;
             }
         }
         $description = Piwik_Translate('PDFReports_DefaultContainingAllReports');
     } else {
         $pdfReports = $this->getReports($idSite, $_period = false, $idReport);
         $pdfReport = reset($pdfReports);
         $reportUniqueIds = explode(',', $pdfReport['reports']);
         $description = $pdfReport['description'];
         // If period wasn't specified, we shall default to the report's period
         if (empty($period)) {
             $period = 'day';
             if ($pdfReport['period'] != 'never') {
                 $period = $pdfReport['period'];
             }
         }
         // If format wasn't specified, defaults to the report's format
         if (empty($reportFormat)) {
             $reportFormat = $pdfReport['format'];
             // Handle cases for reports created before the 'format' field
             if (empty($reportFormat)) {
                 $reportFormat = Piwik_PDFReports::DEFAULT_FORMAT;
             }
         }
         // If $aggregateReportsFormat wasn't specified, defaults to the report configuration
         if (empty($aggregateReportsFormat)) {
             $aggregateReportsFormat = $pdfReport['aggregate_reports_format'];
         }
         // We need to lookup which reports metadata are registered in this report
         $reports = array();
         foreach ($reportMetadata as $metadata) {
             if (in_array($metadata['uniqueId'], $reportUniqueIds)) {
                 $reports[] = $metadata;
             }
         }
     }
     // prepare the report renderer
     $reportRenderer = Piwik_ReportRenderer::factory($reportFormat);
     $reportRenderer->setLocale($language);
     $reportRenderer->setRenderImageInline($outputType == self::OUTPUT_DOWNLOAD ? true : false);
     $description = str_replace(array("\r", "\n"), ' ', $description);
     // The report will be rendered with the first 23 rows and will aggregate other rows in a summary row
     $filterTruncateGET = Piwik_Common::getRequestVar('filter_truncate', false);
     $_GET['filter_truncate'] = 23;
     $websiteName = $prettyDate = false;
     $processedReports = array();
     foreach ($reports as $action) {
         $apiModule = $action['module'];
         $apiAction = $action['action'];
         $apiParameters = array();
         if (isset($action['parameters'])) {
             $apiParameters = $action['parameters'];
         }
         $report = Piwik_API_API::getInstance()->getProcessedReport($idSite, $period, $date, $apiModule, $apiAction, $segment = false, $apiParameters, $idGoal = false, $language);
         $websiteName = $report['website'];
         $prettyDate = $report['prettyDate'];
         $reportMetadata = $report['metadata'];
         $isAggregateReport = !empty($reportMetadata['dimension']);
         $report['displayTable'] = !$isAggregateReport || $aggregateReportsFormat == Piwik_PDFReports::AGGREGATE_REPORTS_FORMAT_TABLES || $aggregateReportsFormat == Piwik_PDFReports::AGGREGATE_REPORTS_FORMAT_TABLES_GRAPHS;
         $report['displayGraph'] = (!$isAggregateReport || $aggregateReportsFormat == Piwik_PDFReports::AGGREGATE_REPORTS_FORMAT_GRAPHS || $aggregateReportsFormat == Piwik_PDFReports::AGGREGATE_REPORTS_FORMAT_TABLES_GRAPHS) && Piwik::isGdExtensionEnabled() && Piwik_PluginsManager::getInstance()->isPluginActivated('ImageGraph') && !empty($reportMetadata['imageGraphUrl']);
         $processedReports[] = $report;
     }
     // Restore values
     if ($filterTruncateGET !== false) {
         $_GET['filter_truncate'] = $filterTruncateGET;
     }
     // generate the report
     $reportRenderer->renderFrontPage($websiteName, $prettyDate, $description, $reports);
     array_walk($processedReports, array($reportRenderer, 'renderReport'));
     switch ($outputType) {
         case self::OUTPUT_SAVE_ON_DISK:
             $outputFilename = 'Email Report - ' . $idReport . '.' . $date . '.' . $idSite . '.' . $language;
             $outputFilename = $reportRenderer->sendToDisk($outputFilename);
             $additionalFiles = array();
             if ($reportFormat == 'html') {
                 foreach ($processedReports as &$report) {
                     if ($report['displayGraph']) {
                         $additionalFile = array();
                         $additionalFile['filename'] = $report['metadata']['name'] . '.png';
                         $additionalFile['cid'] = $report['metadata']['uniqueId'];
                         $additionalFile['content'] = Piwik_ReportRenderer::getStaticGraph($report['metadata']['imageGraphUrl'], Piwik_ReportRenderer_Html::IMAGE_GRAPH_WIDTH, Piwik_ReportRenderer_Html::IMAGE_GRAPH_HEIGHT);
                         $additionalFile['mimeType'] = 'image/png';
                         $additionalFile['encoding'] = Zend_Mime::ENCODING_BASE64;
                         $additionalFiles[] = $additionalFile;
                     }
                 }
             }
             return array($outputFilename, $prettyDate, $websiteName, $reportFormat, $additionalFiles);
             break;
         default:
         case self::OUTPUT_DOWNLOAD:
             $reportRenderer->sendToBrowserDownload("{$websiteName} - {$prettyDate} - {$description}");
             break;
     }
 }
Ejemplo n.º 2
0
 /**
  * Get system information
  */
 public static function getSystemInformation()
 {
     global $piwik_minimumPHPVersion;
     $minimumMemoryLimit = Piwik_Config::getInstance()->General['minimum_memory_limit'];
     $infos = array();
     $infos['general_infos'] = array();
     $infos['directories'] = Piwik::checkDirectoriesWritable();
     $infos['can_auto_update'] = Piwik::canAutoUpdate();
     if (Piwik_Common::isIIS()) {
         Piwik::createWebConfigFiles();
     } else {
         Piwik::createHtAccessFiles();
     }
     Piwik::createWebRootFiles();
     $infos['phpVersion_minimum'] = $piwik_minimumPHPVersion;
     $infos['phpVersion'] = PHP_VERSION;
     $infos['phpVersion_ok'] = version_compare($piwik_minimumPHPVersion, $infos['phpVersion']) === -1;
     // critical errors
     $extensions = @get_loaded_extensions();
     $needed_extensions = array('zlib', 'SPL', 'iconv', 'Reflection');
     $infos['needed_extensions'] = $needed_extensions;
     $infos['missing_extensions'] = array();
     foreach ($needed_extensions as $needed_extension) {
         if (!in_array($needed_extension, $extensions)) {
             $infos['missing_extensions'][] = $needed_extension;
         }
     }
     $infos['pdo_ok'] = false;
     if (in_array('PDO', $extensions)) {
         $infos['pdo_ok'] = true;
     }
     $infos['adapters'] = Piwik_Db_Adapter::getAdapters();
     $needed_functions = array('debug_backtrace', 'create_function', 'eval', 'gzcompress', 'gzuncompress', 'pack');
     $infos['needed_functions'] = $needed_functions;
     $infos['missing_functions'] = array();
     foreach ($needed_functions as $needed_function) {
         if (!self::functionExists($needed_function)) {
             $infos['missing_functions'][] = $needed_function;
         }
     }
     // warnings
     $desired_extensions = array('json', 'libxml', 'dom', 'SimpleXML');
     $infos['desired_extensions'] = $desired_extensions;
     $infos['missing_desired_extensions'] = array();
     foreach ($desired_extensions as $desired_extension) {
         if (!in_array($desired_extension, $extensions)) {
             $infos['missing_desired_extensions'][] = $desired_extension;
         }
     }
     $desired_functions = array('set_time_limit', 'mail', 'parse_ini_file', 'glob');
     $infos['desired_functions'] = $desired_functions;
     $infos['missing_desired_functions'] = array();
     foreach ($desired_functions as $desired_function) {
         if (!self::functionExists($desired_function)) {
             $infos['missing_desired_functions'][] = $desired_function;
         }
     }
     $infos['openurl'] = Piwik_Http::getTransportMethod();
     $infos['gd_ok'] = Piwik::isGdExtensionEnabled();
     $infos['hasMbstring'] = false;
     $infos['multibyte_ok'] = true;
     if (function_exists('mb_internal_encoding')) {
         $infos['hasMbstring'] = true;
         if ((int) ini_get('mbstring.func_overload') != 0) {
             $infos['multibyte_ok'] = false;
         }
     }
     $serverSoftware = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '';
     $infos['serverVersion'] = addslashes($serverSoftware);
     $infos['serverOs'] = @php_uname();
     $infos['serverTime'] = date('H:i:s');
     $infos['registerGlobals_ok'] = ini_get('register_globals') == 0;
     $infos['memoryMinimum'] = $minimumMemoryLimit;
     $infos['memory_ok'] = true;
     $infos['memoryCurrent'] = '';
     $raised = Piwik::raiseMemoryLimitIfNecessary();
     if (($memoryValue = Piwik::getMemoryLimitValue()) > 0) {
         $infos['memoryCurrent'] = $memoryValue . 'M';
         $infos['memory_ok'] = $memoryValue >= $minimumMemoryLimit;
     }
     $infos['isWindows'] = Piwik_Common::isWindows();
     $integrityInfo = Piwik::getFileIntegrityInformation();
     $infos['integrity'] = $integrityInfo[0];
     $infos['integrityErrorMessages'] = array();
     if (isset($integrityInfo[1])) {
         if ($infos['integrity'] == false) {
             $infos['integrityErrorMessages'][] = '<b>' . Piwik_Translate('General_FileIntegrityWarningExplanation') . '</b>';
         }
         $infos['integrityErrorMessages'] = array_merge($infos['integrityErrorMessages'], array_slice($integrityInfo, 1));
     }
     $infos['timezone'] = Piwik::isTimezoneSupportEnabled();
     $infos['tracker_status'] = Piwik_Common::getRequestVar('trackerStatus', 0, 'int');
     $infos['protocol'] = Piwik_ProxyHeaders::getProtocolInformation();
     if (!Piwik::isHttps() && $infos['protocol'] !== null) {
         $infos['general_infos']['secure_protocol'] = '1';
     }
     if (count($headers = Piwik_ProxyHeaders::getProxyClientHeaders()) > 0) {
         $infos['general_infos']['proxy_client_headers'] = $headers;
     }
     if (count($headers = Piwik_ProxyHeaders::getProxyHostHeaders()) > 0) {
         $infos['general_infos']['proxy_host_headers'] = $headers;
     }
     return $infos;
 }
Ejemplo n.º 3
0
 public function get($idSite, $period, $date, $apiModule, $apiAction, $graphType = false, $outputType = Piwik_ImageGraph_API::GRAPH_OUTPUT_INLINE, $column = false, $showMetricTitle = true, $width = false, $height = false, $fontSize = Piwik_ImageGraph_API::DEFAULT_FONT_SIZE, $aliasedGraph = true, $colors = false)
 {
     Piwik::checkUserHasViewAccess($idSite);
     // Health check - should we also test for GD2 only?
     if (!Piwik::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 = Piwik_Translate::getInstance()->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 {
         //Fetch the metadata for given api-action
         $metadata = Piwik_API_API::getInstance()->getMetadata($idSite, $apiModule, $apiAction, $apiParameters = array(), $languageLoaded, $period, $date);
         if (!$metadata) {
             throw new Exception('Invalid API Module and/or API Action');
         }
         $metadata = $metadata[0];
         $reportHasDimension = !empty($metadata['dimension']);
         $constantRowsCount = !empty($metadata['constantRowsCount']);
         $isMultiplePeriod = Piwik_Archive::isMultiplePeriod($date, $period);
         if ($reportHasDimension && $isMultiplePeriod || !$reportHasDimension && !$isMultiplePeriod) {
             throw new Exception('The graph cannot be drawn for this combination of \'date\' and \'period\' parameters.');
         }
         if (empty($graphType)) {
             if ($reportHasDimension) {
                 if ($constantRowsCount) {
                     $graphType = Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_VERTICAL_BAR;
                 } else {
                     $graphType = Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_HORIZONTAL_BAR;
                 }
             } else {
                 $graphType = Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_BASIC_LINE;
             }
             $reportUniqueId = $metadata['uniqueId'];
             if (isset(self::$DEFAULT_GRAPH_TYPE_OVERRIDE[$reportUniqueId])) {
                 $graphType = self::$DEFAULT_GRAPH_TYPE_OVERRIDE[$reportUniqueId];
             }
         } else {
             $availableGraphTypes = Piwik_ImageGraph_StaticGraph::getAvailableStaticGraphTypes();
             if (!in_array($graphType, $availableGraphTypes)) {
                 throw new Exception(Piwik_TranslateException('General_ExceptionInvalidStaticGraphType', array($graphType, implode(', ', $availableGraphTypes))));
             }
         }
         if (empty($width)) {
             $width = self::$DEFAULT_PARAMETERS[$graphType][self::WIDTH_KEY];
         }
         if (empty($height)) {
             $height = self::$DEFAULT_PARAMETERS[$graphType][self::HEIGHT_KEY];
         }
         if ($reportHasDimension) {
             $abscissaColumn = 'label';
         } else {
             // if it's a dimension-less report, the abscissa column can only be the date-index
             $abscissaColumn = 'date';
         }
         $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());
         $ordinateColumn = $column;
         if (empty($ordinateColumn)) {
             $ordinateColumn = self::DEFAULT_ORDINATE_METRIC;
             // if default ordinate metric not available for this report
             if (empty($reportColumns[$ordinateColumn])) {
                 // take the first metric returned in the metadata
                 $ordinateColumn = key($metadata['metrics']);
             }
         }
         // if we still don't have an ordinate column or the one provided by the API caller is invalid
         if (empty($ordinateColumn) || empty($reportColumns[$ordinateColumn])) {
             throw new Exception(Piwik_Translate('ImageGraph_ColumnOrdinateMissing', $ordinateColumn));
         }
         $ordinateLabel = $reportColumns[$ordinateColumn];
         // sort and truncate filters
         $defaultFilterTruncate = self::$DEFAULT_PARAMETERS[$graphType][self::TRUNCATE_KEY];
         switch ($graphType) {
             case Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_3D_PIE:
             case Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_BASIC_PIE:
                 $_GET['filter_sort_column'] = $ordinateColumn;
                 $this->setFilterTruncate($defaultFilterTruncate);
                 break;
             case Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_VERTICAL_BAR:
             case Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_BASIC_LINE:
                 if ($reportHasDimension && !$constantRowsCount) {
                     $this->setFilterTruncate($defaultFilterTruncate);
                 }
                 break;
         }
         $processedReport = Piwik_API_API::getInstance()->getProcessedReport($idSite, $period, $date, $apiModule, $apiAction, $segment = false, $apiParameters = false, $idGoal = false, $languageLoaded);
         // prepare abscissa and ordinate series
         $abscissaSerie = array();
         $ordinateSerie = array();
         $ordinateLogos = array();
         $reportData = $processedReport['reportData'];
         $hasData = false;
         $hasNonZeroValue = false;
         if ($reportHasDimension) {
             $reportMetadata = $processedReport['reportMetadata']->getRows();
             $i = 0;
             // $reportData instanceof Piwik_DataTable
             foreach ($reportData->getRows() as $row) {
                 // $row instanceof Piwik_DataTable_Row
                 $rowData = $row->getColumns();
                 // Associative Array
                 $abscissaSerie[] = Piwik_Common::unsanitizeInputValue($rowData[$abscissaColumn]);
                 $parsedOrdinateValue = $this->parseOrdinateValue($rowData[$ordinateColumn]);
                 $hasData = true;
                 if ($parsedOrdinateValue != 0) {
                     $hasNonZeroValue = true;
                 }
                 $ordinateSerie[] = $parsedOrdinateValue;
                 if (isset($reportMetadata[$i])) {
                     $rowMetadata = $reportMetadata[$i]->getColumns();
                     if (isset($rowMetadata['logo'])) {
                         $ordinateLogos[$i] = $rowMetadata['logo'];
                     }
                 }
                 $i++;
             }
         } else {
             // $reportData instanceof Piwik_DataTable_Array
             $periodsMetadata = array_values($reportData->metadata);
             // $periodsData instanceof Piwik_DataTable_Simple[]
             $periodsData = array_values($reportData->getArray());
             $periodsCount = count($periodsMetadata);
             for ($i = 0; $i < $periodsCount; $i++) {
                 // $periodsData[$i] instanceof Piwik_DataTable_Simple
                 // $rows instanceof Piwik_DataTable_Row[]
                 $rows = $periodsData[$i]->getRows();
                 if (array_key_exists(0, $rows)) {
                     $rowData = $rows[0]->getColumns();
                     // associative Array
                     $ordinateValue = $rowData[$ordinateColumn];
                     $parsedOrdinateValue = $this->parseOrdinateValue($ordinateValue);
                     $hasData = true;
                     if ($parsedOrdinateValue != 0) {
                         $hasNonZeroValue = true;
                     }
                 } else {
                     $parsedOrdinateValue = 0;
                 }
                 $rowId = $periodsMetadata[$i]['period']->getLocalizedShortString();
                 $abscissaSerie[] = Piwik_Common::unsanitizeInputValue($rowId);
                 $ordinateSerie[] = $parsedOrdinateValue;
             }
         }
         if (!$hasData || !$hasNonZeroValue) {
             throw new Exception(Piwik_Translate('General_NoDataForGraph'));
         }
         //Setup the graph
         $graph = Piwik_ImageGraph_StaticGraph::factory($graphType);
         $graph->setWidth($width);
         $graph->setHeight($height);
         $graph->setFont($font);
         $graph->setFontSize($fontSize);
         $graph->setMetricTitle($ordinateLabel);
         $graph->setShowMetricTitle($showMetricTitle);
         $graph->setAliasedGraph($aliasedGraph);
         $graph->setAbscissaSerie($abscissaSerie);
         $graph->setOrdinateSerie($ordinateSerie);
         $graph->setOrdinateLogos($ordinateLogos);
         $graph->setColors(!empty($colors) ? explode(',', $colors) : array());
         // render graph
         $graph->renderGraph();
     } catch (Exception $e) {
         $graph = new Piwik_ImageGraph_StaticGraph_Exception();
         $graph->setWidth($width);
         $graph->setHeight($height);
         $graph->setFont($font);
         $graph->setFontSize($fontSize);
         $graph->setException($e);
         $graph->renderGraph();
     }
     // restoring get parameters
     $_GET = $savedGET;
     switch ($outputType) {
         case self::GRAPH_OUTPUT_FILE:
             // adding the idGoal to the filename
             $idGoal = Piwik_Common::getRequestVar('idGoal', '', 'string');
             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 (!Piwik_Common::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;
     }
 }
Ejemplo n.º 4
0
 /**
  * @param Piwik_Event_Notification $notification notification object
  */
 function processReports($notification)
 {
     if (self::manageEvent($notification)) {
         $processedReports =& $notification->getNotificationObject();
         $notificationInfo = $notification->getNotificationInfo();
         $report = $notificationInfo[Piwik_PDFReports_API::REPORT_KEY];
         $displayFormat = $report['parameters'][self::DISPLAY_FORMAT_PARAMETER];
         foreach ($processedReports as &$processedReport) {
             $metadata = $processedReport['metadata'];
             $isAggregateReport = !empty($metadata['dimension']);
             $processedReport['displayTable'] = $displayFormat != self::DISPLAY_FORMAT_GRAPHS_ONLY;
             $processedReport['displayGraph'] = ($isAggregateReport ? $displayFormat == self::DISPLAY_FORMAT_GRAPHS_ONLY || $displayFormat == self::DISPLAY_FORMAT_TABLES_AND_GRAPHS : $displayFormat != self::DISPLAY_FORMAT_TABLES_ONLY) && Piwik::isGdExtensionEnabled() && Piwik_PluginsManager::getInstance()->isPluginActivated('ImageGraph') && !empty($metadata['imageGraphUrl']);
             // remove evolution metrics from MultiSites.getAll
             if ($metadata['module'] == 'MultiSites') {
                 $columns = $processedReport['columns'];
                 foreach (Piwik_MultiSites_API::getApiMetrics($enhanced = true) as $metricSettings) {
                     unset($columns[$metricSettings[Piwik_MultiSites_API::METRIC_EVOLUTION_COL_NAME_KEY]]);
                 }
                 $processedReport['metadata'] = $metadata;
                 $processedReport['columns'] = $columns;
             }
         }
     }
 }
Ejemplo n.º 5
0
 public function get($idSite, $period, $date, $apiModule, $apiAction, $graphType = false, $outputType = Piwik_ImageGraph_API::GRAPH_OUTPUT_INLINE, $columns = false, $labels = false, $showLegend = true, $width = false, $height = false, $fontSize = Piwik_ImageGraph_API::DEFAULT_FONT_SIZE, $legendFontSize = false, $aliasedGraph = true, $idGoal = false, $colors = false, $idSubtable = false, $legendAppendMetric = true)
 {
     Piwik::checkUserHasViewAccess($idSite);
     // Health check - should we also test for GD2 only?
     if (!Piwik::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 = Piwik_Translate::getInstance()->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 = Piwik_API_API::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 = Piwik_Archive::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 = $fontSize + self::DEFAULT_LEGEND_FONT_SIZE_OFFSET;
         }
         if (empty($graphType)) {
             if ($isMultiplePeriod) {
                 $graphType = Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_BASIC_LINE;
             } else {
                 if ($constantRowsCount) {
                     $graphType = Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_VERTICAL_BAR;
                 } else {
                     $graphType = Piwik_ImageGraph_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 = Piwik_ImageGraph_StaticGraph::getAvailableStaticGraphTypes();
             if (!in_array($graphType, $availableGraphTypes)) {
                 throw new Exception(Piwik_TranslateException('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 Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_3D_PIE:
             case Piwik_ImageGraph_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 Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_VERTICAL_BAR:
             case Piwik_ImageGraph_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 Piwik_API_DataTableGenericFilter for more info)
             if (!$labels) {
                 $savedFilterSortColumnValue = Piwik_Common::getRequestVar('filter_sort_column', '');
                 $_GET['filter_sort_column'] = $plottedMetric;
                 $savedFilterLimitValue = Piwik_Common::getRequestVar('filter_limit', -1, 'int');
                 if ($savedFilterLimitValue == -1 || $savedFilterLimitValue > self::MAX_NB_ROW_LABELS) {
                     $_GET['filter_limit'] = self::DEFAULT_NB_ROW_EVOLUTIONS;
                 }
             }
             $processedReport = Piwik_API_API::getInstance()->getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels, $segment = false, $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 = Piwik_API_API::getInstance()->getProcessedReport($idSite, $period, $date, $apiModule, $apiAction, $segment = false, $apiParameters = false, $idGoal, $languageLoaded, $showTimer = true, $hideMetricsDoc = false, $idSubtable);
         }
         // prepare abscissa and ordinate series
         $abscissaSeries = array();
         $abscissaLogos = array();
         $ordinateSeries = array();
         $reportData = $processedReport['reportData'];
         $hasData = false;
         $hasNonZeroValue = false;
         if (!$isMultiplePeriod) {
             $reportMetadata = $processedReport['reportMetadata']->getRows();
             $i = 0;
             // $reportData instanceof Piwik_DataTable
             foreach ($reportData->getRows() as $row) {
                 // $row instanceof Piwik_DataTable_Row
                 $rowData = $row->getColumns();
                 // Associative Array
                 $abscissaSeries[] = Piwik_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 {
             // $reportData instanceof Piwik_DataTable_Array
             $periodsMetadata = array_values($reportData->metadata);
             // $periodsData instanceof Piwik_DataTable_Simple[]
             $periodsData = array_values($reportData->getArray());
             $periodsCount = count($periodsMetadata);
             for ($i = 0; $i < $periodsCount; $i++) {
                 // $periodsData[$i] instanceof Piwik_DataTable_Simple
                 // $rows instanceof Piwik_DataTable_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 = $periodsMetadata[$i]['period']->getLocalizedShortString();
                 $abscissaSeries[] = Piwik_Common::unsanitizeInputValue($rowId);
             }
         }
         if (!$hasData || !$hasNonZeroValue) {
             throw new Exception(Piwik_Translate('General_NoDataForGraph'));
         }
         //Setup the graph
         $graph = Piwik_ImageGraph_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());
         if ($period == 'day') {
             $graph->setForceSkippedLabels(6);
         }
         // render graph
         $graph->renderGraph();
     } catch (Exception $e) {
         $graph = new Piwik_ImageGraph_StaticGraph_Exception();
         $graph->setWidth($width);
         $graph->setHeight($height);
         $graph->setFont($font);
         $graph->setFontSize($fontSize);
         $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 (!Piwik_Common::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;
     }
 }