function dispatch($notification = null) { if($notification) { $exception = $notification->getNotificationObject(); $message = $exception->getMessage(); } else { $message = ''; } Piwik_Translate::getInstance()->loadCoreTranslation(); Piwik_PostEvent('Installation.startInstallation', $this); $step = Piwik_Common::getRequestVar('action', 'welcome', 'string'); $controller = $this->getInstallationController(); if(in_array($step, array_keys($controller->getInstallationSteps())) || $step == 'saveLanguage') { $controller->$step($message); } else { Piwik::exitWithErrorMessage(Piwik_Translate('Installation_NoConfigFound')); } exit; }
/** * Load translation strings suffixed with _js for a given list of modules. * This function needs to be called when you want to i18n the user interface. * * How to use the function in smarty templates: * {loadJavascriptTranslations plugins='SitesManager CoreHome General'} * * This will load the javascript translations array for the modules specified as parameters. * Only translations string with their ids suffixed with '_js' will be loaded * Note: You can specify disableOutputScriptTag=1 and the returned value won't be enclosed in Javascript tags. * * You can then translate strings in javascript by calling the javascript function: * _pk_translate('MY_TRANSLATION_STRING_js') * * _pk_translate does NOT support printf() arguments, but you can call: * sprintf(_pk_translate('MyPlugin_numberOfEggs_js'),'ten') * where you would have the following in your translation file plugins/MyPlugin/lang/en.php: * 'MyPlugin_numberOfEggs_js' => 'There are %s eggs.' */ function smarty_function_loadJavascriptTranslations($params, &$smarty) { static $pluginTranslationsAlreadyLoaded = array(); if(!isset($params['plugins'])) { throw new Exception("The smarty function loadJavascriptTranslations needs a 'plugins' parameter."); } if(in_array($params['plugins'], $pluginTranslationsAlreadyLoaded)) { return; } $pluginTranslationsAlreadyLoaded[] = $params['plugins']; $jsTranslations = Piwik_Translate::getInstance()->getJavascriptTranslations(explode(' ',$params['plugins'])); $jsCode = ''; if( isset($params['disableOutputScriptTag']) ) { $jsCode .= $jsTranslations; } else { $jsCode .= '<script type="text/javascript">'; $jsCode .= $jsTranslations; $jsCode .= '</script>'; } return $jsCode; }
/** * @group Core * @group Period * @group Period_Year */ public function testGetPrettyString() { Piwik_Translate::getInstance()->loadEnglishTranslation(); $year = new Piwik_Period_Year(Piwik_Date::factory('2024-10-09')); $shouldBe = '2024'; $this->assertEquals($shouldBe, $year->getPrettyString()); }
public function registerTranslation($langCode) { // we are certainly in LogStats mode, Zend is not loaded if (!class_exists('Zend_Loader')) { return; } $infos = $this->getInformation(); if (!isset($infos['translationAvailable'])) { $infos['translationAvailable'] = false; } $translationAvailable = $infos['translationAvailable']; if (!$translationAvailable) { return; } $name = $infos['name']; $path = "plugins/" . $name . "/lang/%s.php"; $defaultLangPath = sprintf($path, $langCode); $defaultEnglishLangPath = sprintf($path, 'en'); $translations = array(); if (Zend_Loader::isReadable($defaultLangPath)) { require $defaultLangPath; } elseif (Zend_Loader::isReadable($defaultEnglishLangPath)) { require $defaultEnglishLangPath; } else { throw new Exception("Language file not found for the plugin '{$name}'."); } Piwik_Translate::getInstance()->addTranslationArray($translations); }
function setUp() { $userFile = PIWIK_INCLUDE_PATH . '/tests/resources/plugins/Actions/Actions.config.ini.php'; Piwik::createConfigObject($userFile); Piwik_Translate::getInstance()->loadEnglishTranslation(); Piwik_Config::getInstance()->setTestEnvironment(); }
function test_callableApiMethods_doNotFail() { Piwik::createConfigObject(); Piwik_Config::getInstance()->setTestEnvironment(); Piwik::createLogObject(); Piwik::createAccessObject(); Piwik::createDatabaseObject(); Piwik::setUserIsSuperUser(); Piwik_Translate::getInstance()->loadEnglishTranslation(); $pluginsManager = Piwik_PluginsManager::getInstance(); $pluginsManager->loadPlugins(Piwik_Config::getInstance()->Plugins['Plugins']); Piwik_SitesManager_API::getInstance()->addSite("name", "http://example.org"); $apiGenerator = new Piwik_API_DocumentationGenerator_CallAllMethods(); $requestUrls = $apiGenerator->getAllRequestsWithParameters(); $this->assertTrue(count($requestUrls) > 20); foreach ($requestUrls as $url) { $call = new Piwik_API_Request($url); $output = $call->process(); // var_dump($url); // var_dump($output); $this->assertTrue(!empty($output)); } Piwik_Translate::getInstance()->unloadEnglishTranslation(); $this->pass(); }
/** * @return Piwik_Translate */ public static function getInstance() { if (self::$instance == null) { $c = __CLASS__; self::$instance = new $c(); } return self::$instance; }
/** * @return Piwik_Translate */ static public function getInstance() { if (self::$instance == null) { self::$instance = new self; } return self::$instance; }
/** * @group Core * @group Piwik * @dataProvider getPrettyTimeFromSecondsData */ public function testGetPrettyTimeFromSeconds($seconds, $expected) { Piwik_Translate::getInstance()->loadEnglishTranslation(); $sentenceExpected = str_replace(' ', ' ', $expected[0]); $numericExpected = $expected[1]; $this->assertEquals($sentenceExpected, Piwik::getPrettyTimeFromSeconds($seconds, $sentence = true)); $this->assertEquals($numericExpected, Piwik::getPrettyTimeFromSeconds($seconds, $sentence = false)); Piwik_Translate::getInstance()->unloadEnglishTranslation(); }
public function test_getPrettyTimeFromSeconds() { Piwik_Translate::getInstance()->loadEnglishTranslation(); $tests = array(30 => array('30s', '00:00:30'), 60 => array('1 min 0s', '00:01:00'), 100 => array('1 min 40s', '00:01:40'), 3600 => array('1 hours 0 min', '01:00:00'), 3700 => array('1 hours 1 min', '01:01:40'), 86400 + 3600 * 10 => array('1 days 10 hours', '34:00:00'), 86400 * 365 => array('365 days 0 hours', '8760:00:00'), 86400 * (365.25 + 10) => array('1 years 10 days', '9006:00:00')); foreach ($tests as $seconds => $expected) { $sentenceExpected = str_replace(' ', ' ', $expected[0]); $numericExpected = $expected[1]; $this->assertEqual(Piwik::getPrettyTimeFromSeconds($seconds, $sentence = true), $sentenceExpected); $this->assertEqual(Piwik::getPrettyTimeFromSeconds($seconds, $sentence = false), $numericExpected); } Piwik_Translate::getInstance()->unloadEnglishTranslation(); }
function dispatch() { Piwik_Translate::getInstance()->loadUserTranslation(); Piwik_PostEvent('Installation.startInstallation', $this); $step = Piwik_Common::getRequestVar('action', 'welcome', 'string'); $controller = $this->getInstallationController(); if (in_array($step, array_keys($controller->getInstallationSteps())) || $step == 'saveLanguage') { $controller->{$step}(); } else { Piwik::exitWithErrorMessage(Piwik_Translate('Installation_NoConfigFound')); } exit; }
/** * inserts javascript translation array into the template from given modules * must be called with 'modules' argument which consists of space-separated module names (i.e. plugins) * * * Example (use in template): * * {loadJavascriptTranslations modules='SitesManager Home General'} * * loads javascript array translations from main translation file ('General') * and both 'Home' and 'SitesManager' plugins translations * * Note: You can put noHtml=1 option in order to output pure JS code * * only translations with '_fs' suffix will be loaded * * in order to use translation in your javascript use _pk_translate function * (it is always loaded with translations): * * <script type="text/javascript"> * alert(_pk_translate('MY_TRANSLATION_STRING')) * </script> * * Note: Use translation string from your translation file WITHOUT '_js' suffix. * * _pk_translate DOES NOT support printf() arguments, but you can call: * * sprintf(_pk_translate('_NB_OF_EGGS'),'ten') * (where _NB_OF_EGGS is defined in translation file as i.e. 'There is %s eggs on the table') * * sprintf() function is by default included when loading translations */ function smarty_function_loadJavascriptTranslations($params, &$smarty) { if (!isset($params['modules'])) { throw new Exception("The smarty function loadJavascriptTranslations needs a 'modules' parameter."); } $translate = Piwik_Translate::getInstance(); $jsTranslations = $translate->getJavascriptTranslations(explode(' ', $params['modules'])); $jsCode = ""; if (isset($params['noHtml'])) { // TODO: add {$PiwikUrl} to the following js include: $jsCode .= "document.write('<scr'+'ipt language=\"javascript\" src=\"libs/javascript/sprintf.js\"><\\/scr'+'ipt>');\n"; $jsCode .= $jsTranslations; } else { // TODO: add {$PiwikUrl} to the following js include: $jsCode .= '<script type="text/javascript" src="libs/javascript/sprintf.js"></script>'; $jsCode .= '<script type="text/javascript">'; $jsCode .= $jsTranslations; $jsCode .= '</script>'; } return $jsCode; }
/** * 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; } }
/** * Tracker requests will automatically trigger the Scheduled tasks. * This is useful for users who don't setup the cron, * but still want daily/weekly/monthly PDF reports emailed automatically. * * This is similar to calling the API CoreAdminHome.runScheduledTasks (see misc/cron/archive.sh) * * @param int $now Current timestamp */ public static function runScheduledTasks($now) { // Currently, there is no hourly tasks. When there are some, // this could be too agressive minimum interval (some hours would be skipped in case of low traffic) $minimumInterval = Piwik_Config::getInstance()->Tracker['scheduled_tasks_min_interval']; // If the user disabled browser archiving, he has already setup a cron // To avoid parallel requests triggering the Scheduled Tasks, // Get last time tasks started executing $cache = Piwik_Common::getCacheGeneral(); if ($minimumInterval <= 0 || empty($cache['isBrowserTriggerArchivingEnabled'])) { printDebug("-> Scheduled tasks not running in Tracker: Browser archiving is disabled."); return; } $nextRunTime = $cache['lastTrackerCronRun'] + $minimumInterval; if (isset($GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS']) && $GLOBALS['PIWIK_TRACKER_DEBUG_FORCE_SCHEDULED_TASKS'] || $cache['lastTrackerCronRun'] === false || $nextRunTime < $now) { $cache['lastTrackerCronRun'] = $now; Piwik_Common::setCacheGeneral($cache); Piwik_Common::initCorePiwikInTrackerMode(); Piwik_SetOption('lastTrackerCronRun', $cache['lastTrackerCronRun']); printDebug('-> Scheduled Tasks: Starting...'); // save current user privilege and temporarily assume super user privilege $isSuperUser = Piwik::isUserIsSuperUser(); // Scheduled tasks assume Super User is running Piwik::setUserIsSuperUser(); // While each plugins should ensure that necessary languages are loaded, // we ensure English translations at least are loaded Piwik_Translate::getInstance()->loadEnglishTranslation(); $resultTasks = Piwik_TaskScheduler::runTasks(); // restore original user privilege Piwik::setUserIsSuperUser($isSuperUser); printDebug($resultTasks); printDebug('Finished Scheduled Tasks.'); } else { printDebug("-> Scheduled tasks not triggered."); } printDebug("Next run will be from: " . date('Y-m-d H:i:s', $nextRunTime) . ' UTC'); }
/** * Must be called before dispatch() * - checks that directories are writable, * - loads the configuration file, * - loads the plugin, * - inits the DB connection, * - etc. */ function init() { static $initialized = false; if($initialized) { return; } $initialized = true; try { Zend_Registry::set('timer', new Piwik_Timer); $directoriesToCheck = array( '/tmp/', '/tmp/templates_c/', '/tmp/cache/', '/tmp/assets/' ); Piwik::checkDirectoriesWritableOrDie($directoriesToCheck); Piwik_Common::assignCliParametersToRequest(); Piwik_Translate::getInstance()->loadEnglishTranslation(); $exceptionToThrow = false; try { Piwik::createConfigObject(); } catch(Exception $e) { Piwik_PostEvent('FrontController.NoConfigurationFile', $e, $info = array(), $pending = true); $exceptionToThrow = $e; } if(Zend_Registry::get('config')->General->maintenance_mode == 1 && !Piwik_Common::isPhpCliMode()) { throw new Exception("Piwik is in scheduled maintenance. Please come back later."); } $pluginsManager = Piwik_PluginsManager::getInstance(); $pluginsManager->loadPlugins( Zend_Registry::get('config')->Plugins->Plugins->toArray() ); if($exceptionToThrow) { throw $exceptionToThrow; } try { Piwik::createDatabaseObject(); } catch(Exception $e) { Piwik_PostEvent('FrontController.badConfigurationFile', $e, $info = array(), $pending = true); throw $e; } Piwik::createLogObject(); // creating the access object, so that core/Updates/* can enforce Super User and use some APIs Piwik::createAccessObject(); Piwik_PostEvent('FrontController.dispatchCoreAndPluginUpdatesScreen'); Piwik_PluginsManager::getInstance()->installLoadedPlugins(); Piwik::install(); // ensure the current Piwik URL is known for later use if(method_exists('Piwik', 'getPiwikUrl')) { $host = Piwik::getPiwikUrl(); } Piwik_PostEvent('FrontController.initAuthenticationObject'); try { $authAdapter = Zend_Registry::get('auth'); } catch(Exception $e){ throw new Exception("Authentication object cannot be found in the Registry. Maybe the Login plugin is not activated? <br />You can activate the plugin by adding:<br /> <code>Plugins[] = Login</code><br /> under the <code>[Plugins]</code> section in your config/config.inc.php"); } Zend_Registry::get('access')->reloadAccess($authAdapter); Piwik_Translate::getInstance()->reloadLanguage(); Piwik::raiseMemoryLimitIfNecessary(); $pluginsManager->postLoadPlugins(); Piwik_PostEvent('FrontController.checkForUpdates'); } catch(Exception $e) { Piwik_ExitWithMessage($e->getMessage(), false, true); } Piwik::log('End FrontController->init() - Request: '. var_export($_REQUEST, true)); }
/** * Generates a PDF file in the browser output. * * @param int $idReport ID of the report to generate. If idReport=0 it will generate a PDF 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 0 = inline PDF, 1 = download PDF, 2 = save to disk PDF, defaults to inline PDF * @param string|false $period Defaults to 'day'. If not specified, will default to the PDF Report's period set when creating the report */ public function generateReport($idReport, $date, $idSite = false, $language = false, $outputType = false, $period = false) { // Load specified language if (empty($language)) { $language = Piwik_Translate::getInstance()->getLanguageDefault(); } Piwik_Translate::getInstance()->reloadLanguage($language); // Available reports static $reportMetadata = null; if (is_null($reportMetadata)) { $reportMetadata = Piwik_API_API::getInstance()->getReportMetadata($idSite); } // Test template: include all reports if ($idReport == 0) { if (empty($period)) { $period = 'day'; } $reports = $reportMetadata; $description = Piwik_Translate('PDFReports_DefaultPDFContainingAllReports'); } 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 PDF Report's period if (empty($period)) { $period = 'day'; if ($pdfReport['period'] != 'never') { $period = $pdfReport['period']; } } // We need to lookup which reports metadata are registered in this PDF $reports = array(); foreach ($reportMetadata as $metadata) { if (in_array($metadata['uniqueId'], $reportUniqueIds)) { $reports[] = $metadata; } } } // PDF will display the first 30 rows, then aggregate other rows in a summary row $filterTruncateGET = Piwik_Common::getRequestVar('filter_truncate', false); $_GET['filter_truncate'] = 30; $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, $language); $websiteName = $report['website']; $prettyDate = $report['prettyDate']; $processedReports[] = $report; } // Restore values if ($filterTruncateGET !== false) { $_GET['filter_truncate'] = $filterTruncateGET; } // Generates the PDF Report $pdf = new Piwik_PDFReports_PDFRenderer($websiteName, $prettyDate, $description, $language); $pdf->paintFirstPage(); foreach ($processedReports as $report) { $pdf->setReport($report['metadata'], $report['reportData'], $report['columns'], $report['reportMetadata']); $pdf->paintReport(); } $outputFilename = 'PDF Report - ' . $idReport . '.' . $date . '.' . $idSite . '.' . $language . '.pdf'; switch ($outputType) { case self::OUTPUT_PDF_SAVE_ON_DISK: $flagOutput = 'F'; $outputFilename = PIWIK_INCLUDE_PATH . '/tmp/' . $outputFilename; @unlink($outputFilename); break; case self::OUTPUT_PDF_DOWNLOAD: $outputFilename = "{$websiteName} - {$prettyDate} - {$description}.pdf"; $flagOutput = 'D'; break; default: case self::OUTPUT_PDF_INLINE_IN_BROWSER: $flagOutput = 'I'; break; } $pdf->Output($outputFilename, $flagOutput); if ($outputType == self::OUTPUT_PDF_SAVE_ON_DISK) { return array($outputFilename, $prettyDate, $websiteName); } }
/** * @group Core * @group Period * @group Period_Range */ public function testGetPrettyString() { Piwik_Translate::getInstance()->loadEnglishTranslation(); $month = new Piwik_Period_Range('range', '2007-02-09,2007-03-15'); $shouldBe = 'From 2007-02-09 to 2007-03-15'; $this->assertEquals($shouldBe, $month->getPrettyString()); }
/** * 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 */ public function generateReport($idReport, $date, $idSite = false, $language = false, $outputType = false, $period = false, $reportFormat = false) { // Load specified language if(empty($language)) { $language = Piwik_Translate::getInstance()->getLanguageDefault(); } Piwik_Translate::getInstance()->reloadLanguage($language); // Available reports static $reportMetadata = null; if(is_null($reportMetadata)) { $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; } $reports = $reportMetadata; $description = Piwik_Translate('PDFReports_DefaultContainingAllReports'); } // Template is a custom template 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; } } // 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; } } } // The report will be rendered with the first 30 rows and will aggregate other rows in a summary row $filterTruncateGET = Piwik_Common::getRequestVar('filter_truncate', false); $_GET['filter_truncate'] = 30; $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']; $processedReports[] = $report; } // Restore values if($filterTruncateGET !== false) { $_GET['filter_truncate'] = $filterTruncateGET; } if(empty($reportFormat)) { $reportFormat = Piwik_PDFReports::DEFAULT_FORMAT; } // Generate the report $reportRenderer = Piwik_ReportRenderer::factory($reportFormat); $reportRenderer->setLocale($language); $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); return array( $outputFilename, $prettyDate, $websiteName, $reportFormat ); break; default: case self::OUTPUT_DOWNLOAD: $reportRenderer->sendToBrowserDownload("$websiteName - $prettyDate - $description"); break; } }
/** * @param Piwik_Plugin $plugin * @param string $langCode */ private function loadTranslation($plugin, $langCode) { // we are certainly in Tracker mode, Zend is not loaded if (!class_exists('Zend_Loader')) { return; } $infos = $plugin->getInformation(); if (!isset($infos['translationAvailable'])) { $infos['translationAvailable'] = false; } $translationAvailable = $infos['translationAvailable']; if (!$translationAvailable) { return; } $pluginName = $plugin->getClassName(); $path = PIWIK_INCLUDE_PATH . "/plugins/" . $pluginName . "/lang/%s.php"; $defaultLangPath = sprintf($path, $langCode); $defaultEnglishLangPath = sprintf($path, 'en'); $translations = array(); if (file_exists($defaultLangPath)) { require $defaultLangPath; } elseif (file_exists($defaultEnglishLangPath)) { require $defaultEnglishLangPath; } else { throw new Exception("Language file not found for the plugin '{$pluginName}'."); } Piwik_Translate::getInstance()->mergeTranslationArray($translations); }
public static function loadPlugins() { Piwik_PluginsManager::getInstance()->setLanguageToLoad(Piwik_Translate::getInstance()->getLanguageToLoad()); Piwik_PluginsManager::getInstance()->setPluginsToLoad(Zend_Registry::get('config')->Plugins->Plugins->toArray()); }
/** * changing the language within one request is a bit fancy * in order to keep the core clean, we need a little hack here * * @param string $langId */ protected function changeLanguage($langId) { if ($this->lastLanguage != $langId) { $_GET['language'] = $langId; Piwik_Translate::reset(); Piwik_Translate::getInstance()->reloadLanguage($langId); } $this->lastLanguage = $langId; }
public function tearDown() { Piwik_Translate::getInstance()->unloadEnglishTranslation(); }
/** * @group Core * @group Period * @group Period_Week */ public function testGetPrettyString() { Piwik_Translate::getInstance()->loadEnglishTranslation(); $week = new Piwik_Period_Week(Piwik_Date::factory('2024-10-09')); $shouldBe = 'From 2024-10-07 to 2024-10-13'; $this->assertEquals($shouldBe, $week->getPrettyString()); }
/** Reset the cached language to load. Used in tests. */ public static function reset() { self::$languageToLoad = null; }
/** * Loads reports metadata, then return the requested one, * matching optional API parameters. */ public function getMetadata($idSite, $apiModule, $apiAction, $apiParameters = array(), $language = false, $period = false, $date = false) { Piwik_Translate::getInstance()->reloadLanguage($language); $reportsMetadata = $this->getReportMetadata($idSite, $period, $date); foreach ($reportsMetadata as $report) { // See ArchiveProcessing/Period.php - unique visitors are not processed for period != day if ($period && $period != 'day' && !($apiModule == 'VisitsSummary' && $apiAction == 'get')) { unset($report['metrics']['nb_uniq_visitors']); } if ($report['module'] == $apiModule && $report['action'] == $apiAction) { // No custom parameters if (empty($apiParameters) && empty($report['parameters'])) { return array($report); } if (empty($report['parameters'])) { continue; } $diff = array_diff($report['parameters'], $apiParameters); if (empty($diff)) { return array($report); } } } return false; }
/** * @return string Two letters language code, eg. "fr" */ public static function getLanguageCodeForCurrentUser() { $languageCode = self::getLanguageFromPreferences(); if (!Piwik_LanguagesManager_API::getInstance()->isLanguageAvailable($languageCode)) { $languageCode = Piwik_Common::extractLanguageCodeFromBrowserLanguage(Piwik_Common::getBrowserLanguage(), Piwik_LanguagesManager_API::getInstance()->getAvailableLanguages()); } if (!Piwik_LanguagesManager_API::getInstance()->isLanguageAvailable($languageCode)) { $languageCode = Piwik_Translate::getInstance()->getLanguageDefault(); } return $languageCode; }
/** * 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 PDFReports.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 = Piwik_Translate::getInstance()->getLanguageDefault(); } Piwik_Translate::getInstance()->reloadLanguage($language); $reports = $this->getReports($idSite = false, $_period = false, $idReport); $report = reset($reports); $idSite = $report['idsite']; $reportType = $report['type']; // 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 report parameters if (!empty($parameters)) { $report['parameters'] = Piwik_Common::json_decode(self::validateReportParameters($reportType, $parameters), true); } else { $parameters = $report['parameters']; } // decode report list $reportUniqueIds = $report['reports']; // available reports $availableReportMetadata = Piwik_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'], $reportUniqueIds)) { $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 = Piwik_Common::getRequestVar('filter_truncate', false); $_GET['filter_truncate'] = self::REPORT_TRUNCATE; $prettyDate = null; $processedReports = array(); 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 if (!empty($userLogin) && $userLogin != Piwik_Config::getInstance()->superuser['login']) { $_GET['_restrictSitesToLogin'] = $userLogin; } } } $processedReport = Piwik_API_API::getInstance()->getProcessedReport($idSite, $period, $date, $apiModule, $apiAction, $segment = false, $apiParameters, $idGoal = false, $language); // TODO add static method getPrettyDate($period, $date) in Piwik_Period $prettyDate = $processedReport['prettyDate']; if ($mustRestoreGET) { $_GET = $mustRestoreGET; } $processedReports[] = $processedReport; } // restore filter truncate parameter value if ($initialFilterTruncate !== false) { $_GET['filter_truncate'] = $initialFilterTruncate; } $notificationInfo = array(self::REPORT_TYPE_INFO_KEY => $reportType, self::REPORT_KEY => $report); // allow plugins to alter processed reports Piwik_PostEvent(self::PROCESS_REPORTS_EVENT, $processedReports, $notificationInfo); // retrieve report renderer instance $reportRenderer = null; Piwik_PostEvent(self::GET_RENDERER_INSTANCE_EVENT, $reportRenderer, $notificationInfo); // init report renderer $reportRenderer->setLocale($language); $reportRenderer->setRenderImageInline($outputType != self::OUTPUT_SAVE_ON_DISK); // render report $websiteName = Piwik_Site::getNameFor($idSite); $description = str_replace(array("\r", "\n"), ' ', $report['description']); $reportRenderer->renderFrontPage($websiteName, $prettyDate, $description, $reportMetadata); 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 = array(); if ($reportRenderer instanceof Piwik_ReportRenderer_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, $additionalFiles); break; case self::OUTPUT_INLINE: $reportRenderer->sendToBrowserInline("{$websiteName} - {$prettyDate} - {$description}"); break; case self::OUTPUT_RETURN: return $reportRenderer->getRenderedReport(); break; default: case self::OUTPUT_DOWNLOAD: $reportRenderer->sendToBrowserDownload("{$websiteName} - {$prettyDate} - {$description}"); break; } }
/** * Must be called before dispatch() * - checks that directories are writable, * - loads the configuration file, * - loads the plugin, * - inits the DB connection, * - etc. */ function init() { try { Zend_Registry::set('timer', new Piwik_Timer()); $directoriesToCheck = array('/tmp', '/tmp/templates_c', '/tmp/cache'); Piwik::checkDirectoriesWritableOrDie($directoriesToCheck); self::assignCliParametersToRequest(); Piwik_Translate::getInstance()->loadEnglishTranslation(); $exceptionToThrow = false; try { Piwik::createConfigObject(); } catch (Exception $e) { Piwik_PostEvent('FrontController.NoConfigurationFile', $e); $exceptionToThrow = $e; } $pluginsManager = Piwik_PluginsManager::getInstance(); $pluginsManager->setPluginsToLoad(Zend_Registry::get('config')->Plugins->Plugins->toArray()); if ($exceptionToThrow) { throw $exceptionToThrow; } Piwik_Translate::getInstance()->loadUserTranslation(); try { Piwik::createDatabaseObject(); } catch (Exception $e) { Piwik_PostEvent('FrontController.badConfigurationFile', $e); throw $e; } Piwik::createLogObject(); // creating the access object, so that core/Updates/* can enforce Super User and use some APIs Piwik::createAccessObject(); Piwik_PostEvent('FrontController.dispatchCoreAndPluginUpdatesScreen'); Piwik_PluginsManager::getInstance()->installLoadedPlugins(); Piwik::install(); Piwik_PostEvent('FrontController.initAuthenticationObject'); try { $authAdapter = Zend_Registry::get('auth'); } catch (Exception $e) { throw new Exception("Authentication object cannot be found in the Registry. Maybe the Login plugin is not activated?\n\t\t\t\t\t\t\t\t\t<br>You can activate the plugin by adding:<br>\n\t\t\t\t\t\t\t\t\t<code>Plugins[] = Login</code><br>\n\t\t\t\t\t\t\t\t\tunder the <code>[Plugins]</code> section in your config/config.inc.php"); } Zend_Registry::get('access')->reloadAccess($authAdapter); Piwik::raiseMemoryLimitIfNecessary(); $pluginsManager->setLanguageToLoad(Piwik_Translate::getInstance()->getLanguageToLoad()); $pluginsManager->postLoadPlugins(); Piwik_PostEvent('FrontController.checkForUpdates'); } catch (Exception $e) { Piwik_ExitWithMessage($e->getMessage(), $e->getTraceAsString(), true); } }
/** * Must be called before dispatch() * - checks that directories are writable, * - loads the configuration file, * - loads the plugin, * - inits the DB connection, * - etc. */ function init() { static $initialized = false; if ($initialized) { return; } $initialized = true; try { Zend_Registry::set('timer', new Piwik_Timer()); $directoriesToCheck = array('/tmp/', '/tmp/templates_c/', '/tmp/cache/', '/tmp/assets/', '/tmp/tcpdf/'); Piwik::checkDirectoriesWritableOrDie($directoriesToCheck); Piwik_Common::assignCliParametersToRequest(); Piwik_Translate::getInstance()->loadEnglishTranslation(); $exceptionToThrow = false; try { Piwik::createConfigObject(); } catch (Exception $e) { Piwik_PostEvent('FrontController.NoConfigurationFile', $e, $info = array(), $pending = true); $exceptionToThrow = $e; } if (Piwik_Session::isFileBasedSessions()) { Piwik_Session::start(); } if (Piwik_Config::getInstance()->General['maintenance_mode'] == 1 && !Piwik_Common::isPhpCliMode()) { $format = Piwik_Common::getRequestVar('format', ''); $exception = new Exception("Piwik is in scheduled maintenance. Please come back later."); if (empty($format)) { throw $exception; } $response = new Piwik_API_ResponseBuilder($format); echo $response->getResponseException($exception); exit; } if (!Piwik_Common::isPhpCliMode() && Piwik_Config::getInstance()->General['force_ssl'] == 1 && !Piwik::isHttps()) { $url = Piwik_Url::getCurrentUrl(); $url = str_replace("http://", "https://", $url); Piwik_Url::redirectToUrl($url); } $pluginsManager = Piwik_PluginsManager::getInstance(); $pluginsToLoad = Piwik_Config::getInstance()->Plugins['Plugins']; $pluginsManager->loadPlugins($pluginsToLoad); if ($exceptionToThrow) { throw $exceptionToThrow; } try { Piwik::createDatabaseObject(); } catch (Exception $e) { if (self::shouldRethrowException()) { throw $e; } Piwik_PostEvent('FrontController.badConfigurationFile', $e, $info = array(), $pending = true); throw $e; } Piwik::createLogObject(); // creating the access object, so that core/Updates/* can enforce Super User and use some APIs Piwik::createAccessObject(); Piwik_PostEvent('FrontController.dispatchCoreAndPluginUpdatesScreen'); Piwik_PluginsManager::getInstance()->installLoadedPlugins(); Piwik::install(); // ensure the current Piwik URL is known for later use if (method_exists('Piwik', 'getPiwikUrl')) { $host = Piwik::getPiwikUrl(); } Piwik_PostEvent('FrontController.initAuthenticationObject'); try { $authAdapter = Zend_Registry::get('auth'); } catch (Exception $e) { throw new Exception("Authentication object cannot be found in the Registry. Maybe the Login plugin is not activated?\n\t\t\t\t\t\t\t\t\t<br />You can activate the plugin by adding:<br />\n\t\t\t\t\t\t\t\t\t<code>Plugins[] = Login</code><br />\n\t\t\t\t\t\t\t\t\tunder the <code>[Plugins]</code> section in your config/config.ini.php"); } Zend_Registry::get('access')->reloadAccess($authAdapter); Piwik::raiseMemoryLimitIfNecessary(); Piwik_Translate::getInstance()->reloadLanguage(); $pluginsManager->postLoadPlugins(); Piwik_PostEvent('FrontController.checkForUpdates'); } catch (Exception $e) { if (self::shouldRethrowException()) { throw $e; } Piwik_ExitWithMessage($e->getMessage(), false, true); } // Piwik::log('End FrontController->init() - Request: '. var_export($_REQUEST, true)); }
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; } }