/** * Get translation file path * * @param string $lang ISO 639-1 alpha-2 language code * @param string $base Optional base directory (either 'lang' or 'tmp') * @throws Exception * @return string path */ public static function getTranslationPath($lang, $base = 'lang') { if (!Piwik_Common::isValidFilename($lang) || $base !== 'lang' && $base !== 'tmp') { throw new Exception(Piwik_TranslateException('General_ExceptionLanguageFileNotFound', array($lang))); } return PIWIK_INCLUDE_PATH . '/' . $base . '/' . $lang . '.php'; }
/** * Enter description here... * * @return string the language filename prefix, eg "en" for english * @throws exception if the language set in the config file is not a valid filename */ public function getLanguageToLoad() { $language = Zend_Registry::get('config')->Language->current; if (Piwik_Common::isValidFilename($language)) { return $language; } else { throw new Exception("The language selected ('{$language}') is not a valid language file "); } }
private function loadTranslation($language) { $path = PIWIK_INCLUDE_PATH . '/lang/' . $language . '.php'; if (!Piwik_Common::isValidFilename($language) || !is_readable($path)) { throw new Exception(Piwik_TranslateException('General_ExceptionLanguageFileNotFound', array($language))); } require $path; $this->mergeTranslationArray($translations); $this->setLocale(); $this->loadedLanguage = $language; }
/** * Returns the DataTable associated to the output format $name * * @throws exception If the renderer is unknown * @return Piwik_DataTable_Renderer */ public static function factory($name) { $name = ucfirst(strtolower($name)); $path = "DataTable/Renderer/" . $name . ".php"; $className = 'Piwik_DataTable_Renderer_' . $name; if (Piwik_Common::isValidFilename($name) && Zend_Loader::isReadable($path)) { require_once $path; return new $className(); } else { throw new Exception("Renderer format '{$name}' not valid. Try 'xml' or 'json' or 'csv' or 'html' or 'php' or 'original' instead."); } }
/** * @return string the language filename prefix, eg 'en' for english * @throws exception if the language set is not a valid filename */ public function getLanguageToLoad() { static $language = null; if (!is_null($language)) { return $language; } Piwik_PostEvent('Translate.getLanguageToLoad', $language); if (is_null($language) || empty($language)) { $language = Zend_Registry::get('config')->General->default_language; } if (Piwik_Common::isValidFilename($language)) { return $language; } else { throw new Exception("The language selected ('{$language}') is not a valid language file "); } }
/** * Loads the plugin filename and instanciates the plugin with the given name, eg. UserCountry * Do NOT give the class name ie. Piwik_UserCountry, but give the plugin name ie. UserCountry * * @param Piwik_Plugin $pluginName */ public function loadPlugin($pluginName) { if (isset($this->loadedPlugins[$pluginName])) { return $this->loadedPlugins[$pluginName]; } $pluginFileName = $pluginName . '/' . $pluginName . ".php"; $pluginClassName = "Piwik_" . $pluginName; if (!Piwik_Common::isValidFilename($pluginName)) { throw new Exception("The plugin filename '{$pluginFileName}' is not a valid filename"); } $path = PIWIK_INCLUDE_PATH . '/plugins/' . $pluginFileName; if (!file_exists($path)) { throw new Exception("The plugin '{$pluginName}' is enabled, but the file '{$path}' couldn't be found.\n\t\t\t\t\t\t\tTo continue, please disable the plugin manually by removing the line \n\t\t\t\t\t\t\t<pre>Plugins[] = {$pluginName}</pre>\n\t\t\t\t\t\t\tin the configuration file <code>config/config.ini.php</code>"); } require_once $path; if (!class_exists($pluginClassName)) { throw new Exception("The class {$pluginClassName} couldn't be found in the file '{$path}'"); } $newPlugin = new $pluginClassName(); if (!$newPlugin instanceof Piwik_Plugin) { throw new Exception("The plugin {$pluginClassName} in the file {$path} must inherit from Piwik_Plugin."); } return $newPlugin; }
public function test_isValidFilenameNotValidValues() { $notvalid = array("../test", "/etc/htpasswd", '$var', ';test', '[bizarre]', '', ".htaccess", "very long long eogaioge ageja geau ghaeihieg heiagie aiughaeui hfilename"); foreach ($notvalid as $toTest) { $this->assertFalse(Piwik_Common::isValidFilename($toTest), $toTest . " valid but shouldn't!"); } }
/** * Returns true if specified language is available * * @param string $languageCode * @return bool true if language available; false otherwise */ public function isLanguageAvailable($languageCode) { return $languageCode !== false && Piwik_Common::isValidFilename($languageCode) && in_array($languageCode, $this->getAvailableLanguages()); }
/** * Loads the plugin filename and instantiates the plugin with the given name, eg. UserCountry * Do NOT give the class name ie. Piwik_UserCountry, but give the plugin name ie. UserCountry * * @param string $pluginName * @throws Exception * @return Piwik_Plugin|null */ public function loadPlugin($pluginName) { if (isset($this->loadedPlugins[$pluginName])) { return $this->loadedPlugins[$pluginName]; } $pluginFileName = $pluginName . '/' . $pluginName . '.php'; $pluginClassName = 'Piwik_' . $pluginName; if (!Piwik_Common::isValidFilename($pluginName)) { throw new Exception("The plugin filename '{$pluginFileName}' is not a valid filename"); } $path = PIWIK_INCLUDE_PATH . '/plugins/' . $pluginFileName; if (!file_exists($path)) { // Piwik::log("Unable to load plugin '$pluginName' because '$path' couldn't be found."); return null; } // Don't remove this. // Our autoloader can't find plugins/PluginName/PluginName.php require_once $path; // prefixed by PIWIK_INCLUDE_PATH if (!class_exists($pluginClassName, false)) { throw new Exception("The class {$pluginClassName} couldn't be found in the file '{$path}'"); } $newPlugin = new $pluginClassName(); if (!$newPlugin instanceof Piwik_Plugin) { throw new Exception("The plugin {$pluginClassName} in the file {$path} must inherit from Piwik_Plugin."); } $this->addLoadedPlugin($pluginName, $newPlugin); return $newPlugin; }
/** * Loads the plugin filename and instanciates the plugin with the given name, eg. UserCountry * Do NOT give the class name ie. Piwik_UserCountry, but give the plugin name ie. UserCountry * * @param Piwik_Plugin $pluginName */ public function loadPlugin($pluginName) { if (isset($this->loadedPlugins[$pluginName])) { return $this->loadedPlugins[$pluginName]; } $pluginFileName = $pluginName . '/' . $pluginName . '.php'; $pluginClassName = 'Piwik_' . $pluginName; if (!Piwik_Common::isValidFilename($pluginName)) { throw new Exception("The plugin filename '{$pluginFileName}' is not a valid filename"); } $path = PIWIK_INCLUDE_PATH . '/plugins/' . $pluginFileName; if (!file_exists($path)) { throw new Exception("Unable to load plugin '{$pluginName}' because '{$path}' couldn't be found.\n\t\t\tYou can manually uninstall the plugin by removing the line <code>Plugins[] = {$pluginName}</code> from the Piwik config file."); } // Don't remove this. // Our autoloader can't find plugins/PluginName/PluginName.php require_once $path; // prefixed by PIWIK_INCLUDE_PATH if (!class_exists($pluginClassName, false)) { throw new Exception("The class {$pluginClassName} couldn't be found in the file '{$path}'"); } $newPlugin = new $pluginClassName(); if (!$newPlugin instanceof Piwik_Plugin) { throw new Exception("The plugin {$pluginClassName} in the file {$path} must inherit from Piwik_Plugin."); } return $newPlugin; }
/** * Loads the plugin filename and instantiates the plugin with the given name, eg. UserCountry * Do NOT give the class name ie. Piwik_UserCountry, but give the plugin name ie. UserCountry * * @param string $pluginName * @throws Exception * @return Piwik_Plugin|null */ public function loadPlugin($pluginName) { if (isset($this->loadedPlugins[$pluginName])) { return $this->loadedPlugins[$pluginName]; } $pluginFileName = sprintf("%s/%s.php", $pluginName, $pluginName); $pluginClassName = sprintf('Piwik_%s', $pluginName); if (!Piwik_Common::isValidFilename($pluginName)) { throw new Exception(sprintf("The plugin filename '%s' is not a valid filename", $pluginFileName)); } $path = PIWIK_INCLUDE_PATH . '/plugins/' . $pluginFileName; if (!file_exists($path)) { // ToDo: We should log this - but this will crash in Tracker mode since core/Piwik is not loaded //Piwik::log(sprintf("Unable to load plugin '%s' because '%s' couldn't be found.", $pluginName, $path)); throw new Exception(sprintf("Unable to load plugin '%s' because '%s' couldn't be found.", $pluginName, $path)); } // Don't remove this. // Our autoloader can't find plugins/PluginName/PluginName.php require_once $path; // prefixed by PIWIK_INCLUDE_PATH if (!class_exists($pluginClassName, false)) { throw new Exception("The class {$pluginClassName} couldn't be found in the file '{$path}'"); } $newPlugin = new $pluginClassName(); if (!$newPlugin instanceof Piwik_Plugin) { throw new Exception("The plugin {$pluginClassName} in the file {$path} must inherit from Piwik_Plugin."); } $this->addLoadedPlugin($pluginName, $newPlugin); return $newPlugin; }
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; } }
/** * Loads the plugin filename and instanciates the plugin with the given name, eg. UserCountry * Do NOT give the class name ie. Piwik_UserCountry, but give the plugin name ie. UserCountry * * @param Piwik_Plugin $pluginName */ public function loadPlugin($pluginName) { if (isset($this->loadedPlugins[$pluginName])) { return $this->loadedPlugins[$pluginName]; } $pluginFileName = $pluginName . '/' . $pluginName . ".php"; $pluginClassName = "Piwik_" . $pluginName; if (!Piwik_Common::isValidFilename($pluginName)) { throw new Exception("The plugin filename '{$pluginFileName}' is not a valid filename"); } $path = 'plugins/' . $pluginFileName; // case LogStats, we don't throw the exception, we don't want to add the Zend overhead if (class_exists('Zend_Loader') && !Zend_Loader::isReadable($path)) { throw new Exception("The plugin file {$path} couldn't be found."); } require_once $path; if (!class_exists($pluginClassName)) { throw new Exception("The class {$pluginClassName} couldn't be found in the file '{$path}'"); } $newPlugin = new $pluginClassName(); if (!$newPlugin instanceof Piwik_Plugin) { throw new Exception("The plugin {$pluginClassName} in the file {$path} must inherit from Piwik_Plugin."); } return $newPlugin; }
/** * @return string the language filename prefix, eg 'en' for english * @throws exception if the language set is not a valid filename */ public function getLanguageToLoad() { static $language = null; if(!is_null($language)) { return $language; } Piwik_PostEvent('Translate.getLanguageToLoad', $language); $language = Piwik_Common::getRequestVar('language', is_null($language) ? '' : $language, 'string'); if(empty($language)) { $language = $this->getLanguageDefault(); } if( Piwik_Common::isValidFilename($language)) { return $language; } else { throw new Exception("The language selected ('$language') is not a valid language file "); } }
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; } }
function validateOwner() { return Piwik_Common::isValidFilename($this->owner->getValue()); }