public function __construct($string, $idSites) { $string = Piwik_Common::unsanitizeInputValue($string); $string = trim($string); if( !Piwik_Archive::isSegmentationEnabled() && !empty($string)) { throw new Exception("The Super User has disabled the use of 'segments' for the anonymous user. Please log in to use Segmentation in the API."); } // As a preventive measure, we restrict the filter size to a safe limit $string = substr($string, 0, self::SEGMENT_TRUNCATE_LIMIT); $this->string = $string; $this->idSites = $idSites; $segment = new Piwik_SegmentExpression($string); $this->segment = $segment; // parse segments $expressions = $segment->parseSubExpressions(); // convert segments name to sql segment // check that user is allowed to view this segment // and apply a filter to the value to match if necessary (to map DB fields format) $cleanedExpressions = array(); foreach($expressions as $expression) { $operand = $expression[Piwik_SegmentExpression::INDEX_OPERAND]; $cleanedExpression = $this->getCleanedExpression($operand); $expression[Piwik_SegmentExpression::INDEX_OPERAND] = $cleanedExpression; $cleanedExpressions[] = $expression; } $segment->setSubExpressionsAfterCleanup($cleanedExpressions); }
public function setGeneralSettings() { Piwik::checkUserIsSuperUser(); $response = new Piwik_API_ResponseBuilder(Piwik_Common::getRequestVar('format')); try { $this->checkTokenInUrl(); $enableBrowserTriggerArchiving = Piwik_Common::getRequestVar('enableBrowserTriggerArchiving'); $todayArchiveTimeToLive = Piwik_Common::getRequestVar('todayArchiveTimeToLive'); Piwik_ArchiveProcessing::setBrowserTriggerArchiving((bool) $enableBrowserTriggerArchiving); Piwik_ArchiveProcessing::setTodayArchiveTimeToLive($todayArchiveTimeToLive); // Update email settings $mail = array(); $mail['transport'] = Piwik_Common::getRequestVar('mailUseSmtp') == '1' ? 'smtp' : ''; $mail['port'] = Piwik_Common::getRequestVar('mailPort', ''); $mail['host'] = Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar('mailHost', '')); $mail['type'] = Piwik_Common::getRequestVar('mailType', ''); $mail['username'] = Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar('mailUsername', '')); $mail['password'] = Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar('mailPassword', '')); $mail['encryption'] = Piwik_Common::getRequestVar('mailEncryption', ''); Piwik_Config::getInstance()->mail = $mail; // update branding settings Piwik_Config::getInstance()->branding['use_custom_logo'] = Piwik_Common::getRequestVar('useCustomLogo', '0'); $toReturn = $response->getResponse(); } catch (Exception $e) { $toReturn = $response->getResponseException($e); } echo $toReturn; }
public static function getAllDashboards($login) { $dashboards = Piwik_FetchAll('SELECT iddashboard, name FROM ' . Piwik_Common::prefixTable('user_dashboard') . ' WHERE login = ? ORDER BY iddashboard', array($login)); $pos = 0; $nameless = 1; foreach ($dashboards as &$dashboard) { if (!empty($dashboard['name'])) { $dashboard['name'] = $dashboard['name']; } else { $dashboard['name'] = Piwik_Translate('Dashboard_DashboardOf', $login); if ($nameless > 1) { $dashboard['name'] .= " ({$nameless})"; } if (empty($dashboard['layout'])) { $layout = '[]'; } else { $layout = html_entity_decode($dashboard['layout']); $layout = str_replace("\\\"", "\"", $layout); } $dashboard['layout'] = Piwik_Common::json_decode($layout); $nameless++; } $dashboard['name'] = Piwik_Common::unsanitizeInputValue($dashboard['name']); $pos++; } return $dashboards; }
function worldMap() { if (!Piwik_PluginsManager::getInstance()->isPluginActivated('UserCountry')) { return ''; } $idSite = Piwik_Common::getRequestVar('idSite', 1, 'int'); Piwik::checkUserHasViewAccess($idSite); $period = Piwik_Common::getRequestVar('period'); $date = Piwik_Common::getRequestVar('date'); $token_auth = Piwik::getCurrentUserTokenAuth(); $view = Piwik_View::factory('worldmap'); $view->dataUrl = "?module=API" . "&method=API.getProcessedReport&format=XML" . "&apiModule=UserCountry&apiAction=getCountry" . "&idSite=" . $idSite . "&period=" . $period . "&date=" . $date . "&token_auth=" . $token_auth . "&segment=" . Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar('segment', '')) . "&filter_limit=-1"; // definition of the color scale $view->hueMin = 218; $view->hueMax = 216; $view->satMin = "0.285"; $view->satMax = "0.9"; $view->lgtMin = ".97"; $view->lgtMax = ".44"; $request = new Piwik_API_Request('method=API.getMetadata&format=PHP' . '&apiModule=UserCountry&apiAction=getCountry' . '&idSite=' . $idSite . '&period=' . $period . '&date=' . $date . '&token_auth=' . $token_auth . '&filter_limit=-1'); $metaData = $request->process(); $metrics = array(); foreach ($metaData[0]['metrics'] as $id => $val) { if (Piwik_Common::getRequestVar('period') == 'day' || $id != 'nb_uniq_visitors') { $metrics[] = array($id, $val); } } foreach ($metaData[0]['processedMetrics'] as $id => $val) { $metrics[] = array($id, $val); } $view->metrics = $metrics; $view->defaultMetric = 'nb_visits'; echo $view->render(); }
/** * The constructor * Initialize some local variables from the request * @param int $idSite * @param Piwik_Date $date ($this->date from controller) * @throws Exception */ public function __construct($idSite, $date, $graphType = null) { $this->apiMethod = Piwik_Common::getRequestVar('apiMethod', '', 'string'); if (empty($this->apiMethod)) { throw new Exception("Parameter apiMethod not set."); } $this->label = Piwik_Common::getRequestVar('label', '', 'string'); $this->label = Piwik_Common::unsanitizeInputValue($this->label); if ($this->label === '') { throw new Exception("Parameter label not set."); } $this->period = Piwik_Common::getRequestVar('period', '', 'string'); if (empty($this->period)) { throw new Exception("Parameter period not set."); } $this->idSite = $idSite; $this->graphType = $graphType; if ($this->period != 'range') { // handle day, week, month and year: display last X periods $end = $date->toString(); list($this->date, $lastN) = Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution::getDateRangeAndLastN($this->period, $end); } $this->segment = Piwik_Common::getRequestVar('segment', '', 'string'); $this->loadEvolutionReport(); }
/** * send email to Piwik team and display nice thanks */ function sendFeedback() { $email = Piwik_Common::getRequestVar('email', '', 'string'); $body = Piwik_Common::getRequestVar('body', '', 'string'); $category = Piwik_Common::getRequestVar('category', '', 'string'); $nonce = Piwik_Common::getRequestVar('nonce', '', 'string'); $view = Piwik_View::factory('sent'); $view->feedbackEmailAddress = Zend_Registry::get('config')->General->feedback_email_address; try { $minimumBodyLength = 35; if (strlen($body) < $minimumBodyLength) { throw new Exception(Piwik_TranslateException('Feedback_ExceptionBodyLength', array($minimumBodyLength))); } if (!Piwik::isValidEmailString($email)) { throw new Exception(Piwik_TranslateException('UsersManager_ExceptionInvalidEmail')); } if (preg_match('/https?:/i', $body)) { throw new Exception(Piwik_TranslateException('Feedback_ExceptionNoUrls')); } if (!Piwik_Nonce::verifyNonce('Piwik_Feedback.sendFeedback', $nonce)) { throw new Exception(Piwik_TranslateException('General_ExceptionNonceMismatch')); } Piwik_Nonce::discardNonce('Piwik_Feedback.sendFeedback'); $mail = new Piwik_Mail(); $mail->setFrom(Piwik_Common::unsanitizeInputValue($email)); $mail->addTo($view->feedbackEmailAddress, 'Piwik Team'); $mail->setSubject('[ Feedback form - Piwik ] ' . $category); $mail->setBodyText(Piwik_Common::unsanitizeInputValue($body) . "\n" . 'Piwik ' . Piwik_Version::VERSION . "\n" . 'IP: ' . Piwik_Common::getIpString() . "\n" . 'URL: ' . Piwik_Url::getReferer() . "\n"); @$mail->send(); } catch (Exception $e) { $view->ErrorString = $e->getMessage(); $view->message = $body; } echo $view->render(); }
public function setAxisYValues(&$values) { foreach ($values as $label => &$data) { $this->series[] = array('label' => Piwik_Common::unsanitizeInputValue($label), 'internalLabel' => $label); array_walk($data, create_function('&$v', '$v = (float)$v;')); $this->data[] =& $data; } }
public function oneClickResults() { Piwik_API_Request::reloadAuthUsingTokenAuth($_POST); Piwik::checkUserIsSuperUser(); $view = Piwik_View::factory('update_one_click_results'); $view->coreError = Piwik_Common::getRequestVar('error', '', 'string', $_POST); $view->feedbackMessages = safe_unserialize(Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar('messages', '', 'string', $_POST))); echo $view->render(); }
/** * This method combines various reports (both from this and from other plugins) and * returns a complete report. The report is used in the Transitions API to load all * data at once. */ public function getFullReport($pageUrl, $idSite, $period, $date, $segment = false, $limitBeforeGrouping = false) { Piwik::checkUserHasViewAccess($idSite); $pageUrl = Piwik_Common::unsanitizeInputValue($pageUrl); $report = array(); $this->addMainPageMetricsToReport($report, $pageUrl, $idSite, $period, $date, $segment); $this->addLiveTransitionsDataToReport($report, $pageUrl, $idSite, $period, $date, $segment, $limitBeforeGrouping); // replace column names in the data tables $columnNames = array('label' => 'url', Piwik_Archive::INDEX_NB_ACTIONS => 'referrals'); $reportNames = array('previousPages', 'followingPages', 'outlinks', 'downloads'); foreach ($reportNames as $reportName) { if (isset($report[$reportName])) { $report[$reportName]->filter('ReplaceColumnNames', array($columnNames)); } } return $report; }
public function setColumnsToDisplay($columnsNames) { $newColumnsNames = array(); $goals = array(); $idSite = $this->getIdSite(); if ($idSite) { $goals = Piwik_Goals_API::getInstance()->getGoals($idSite); $ecommerceGoal = array('idgoal' => Piwik_Archive::LABEL_ECOMMERCE_ORDER, 'name' => Piwik_Translate('Goals_EcommerceOrder')); $site = new Piwik_Site($idSite); //Case Ecommerce report table if ($this->isEcommerce) { $goals = array($ecommerceGoal); } elseif ($site->isEcommerceEnabled()) { $goals = array_merge(array($ecommerceGoal), $goals); } } foreach ($columnsNames as $columnName) { if (in_array($columnName, array('goal_%s_conversion_rate', 'goal_%s_nb_conversions', 'goal_%s_revenue_per_visit', 'goal_%s_revenue', 'goal_%s_avg_order_revenue', 'goal_%s_items'))) { foreach ($goals as $goal) { $idgoal = $goal['idgoal']; // Columns names are escaped in smarty via | escape:'html' $goal['name'] = Piwik_Common::unsanitizeInputValue($goal['name']); if ($this->processOnlyIdGoal > Piwik_DataTable_Filter_AddColumnsProcessedMetricsGoal::GOALS_FULL_TABLE && $this->processOnlyIdGoal != $idgoal && !$this->isEcommerce) { continue; } $name = Piwik_Translate($this->getColumnTranslation($columnName), $goal['name']); $columnNameGoal = str_replace('%s', $idgoal, $columnName); $this->setColumnTranslation($columnNameGoal, $name); $this->setDynamicMetricDocumentation($columnName, $columnNameGoal, $goal['name'], $goal['idgoal']); if (strpos($columnNameGoal, '_rate') === false && $this->processOnlyIdGoal == Piwik_DataTable_Filter_AddColumnsProcessedMetricsGoal::GOALS_OVERVIEW) { continue; } if (strstr($columnNameGoal, '_revenue') !== false) { $this->columnsToRevenueFilter[] = $columnNameGoal; } else { $this->columnsToConversionFilter[] = $columnNameGoal; } $newColumnsNames[] = $columnNameGoal; } } else { $newColumnsNames[] = $columnName; } } parent::setColumnsToDisplay($newColumnsNames); }
/** * The constructor * Initialize some local variables from the request * @param int $idSite * @param Piwik_Date $date ($this->date from controller) * @throws Exception */ public function __construct($idSite, $date) { $this->apiMethod = Piwik_Common::getRequestVar('apiMethod', '', 'string'); if (empty($this->apiMethod)) { throw new Exception("Parameter apiMethod not set."); } $this->label = Piwik_Common::getRequestVar('label', '', 'string'); $this->label = Piwik_Common::unsanitizeInputValue($this->label); if ($this->label === '') { throw new Exception("Parameter label not set."); } $this->period = Piwik_Common::getRequestVar('period', '', 'string'); if (empty($this->period)) { throw new Exception("Parameter period not set."); } $this->idSite = $idSite; if ($this->period != 'range') { // handle day, week, month and year: display last X periods $end = $date->toString(); if ($this->period == 'year') { $start = $date->subYear(10)->toString(); } else { if ($this->period == 'month') { $start = $date->subMonth(30)->toString(); } else { if ($this->period == 'week') { $start = $date->subWeek(30)->toString(); } else { $start = $date->subDay(30)->toString(); } } } $this->date = $start . ',' . $end; } $this->segment = Piwik_Common::getRequestVar('segment', '', 'string'); $this->loadEvolutionReport(); }
/** * This method is called when the JS from startOverlaySession() detects that the target domain * is not configured for the current site. */ public function showErrorWrongDomain() { $idSite = Piwik_Common::getRequestVar('idSite', 0, 'int'); Piwik::checkUserHasViewAccess($idSite); $url = Piwik_Common::getRequestVar('url', ''); $url = Piwik_Common::unsanitizeInputValue($url); $message = Piwik_Translate('Overlay_RedirectUrlError', array($url, "\n")); $message = nl2br(htmlentities($message)); $view = Piwik_View::factory('error_wrong_domain'); $view->message = $message; if (Piwik::isUserHasAdminAccess($idSite)) { // TODO use $idSite to link to the correct row. This is tricky because the #rowX ids don't match // the site ids when sites have been deleted. $url = 'index.php?module=SitesManager&action=index'; $troubleshoot = htmlentities(Piwik_Translate('Overlay_RedirectUrlErrorAdmin')); $troubleshoot = sprintf($troubleshoot, '<a href="' . $url . '" target="_top">', '</a>'); $view->troubleshoot = $troubleshoot; } else { $view->troubleshoot = htmlentities(Piwik_Translate('Overlay_RedirectUrlErrorUser')); } echo $view->render(); }
/** * Saves the layout as default */ public function saveLayoutAsDefault() { $this->checkTokenInUrl(); if (Piwik::isUserIsSuperUser()) { $layout = Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar('layout')); $paramsBind = array('', '1', $layout, $layout); Piwik_Query('INSERT INTO ' . Piwik_Common::prefixTable('user_dashboard') . ' (login, iddashboard, layout) VALUES (?,?,?) ON DUPLICATE KEY UPDATE layout=?', $paramsBind); } }
/** * Form-less login * @see how to use it on http://piwik.org/faq/how-to/#faq_30 * @param none * @return void */ function logme() { self::checkForceSslLogin(); $password = Piwik_Common::getRequestVar('password', null, 'string'); if (strlen($password) != 32) { throw new Exception(Piwik_TranslateException('Login_ExceptionPasswordMD5HashExpected')); } $login = Piwik_Common::getRequestVar('login', null, 'string'); if ($login == Zend_Registry::get('config')->superuser->login) { throw new Exception(Piwik_TranslateException('Login_ExceptionInvalidSuperUserAuthenticationMethod', array("logme"))); } $currentUrl = 'index.php'; if (($idSite = Piwik_Common::getRequestVar('idSite', false, 'int')) !== false) { $currentUrl .= '?idSite=' . $idSite; } $urlToRedirect = Piwik_Common::getRequestVar('url', $currentUrl, 'string'); $urlToRedirect = Piwik_Common::unsanitizeInputValue($urlToRedirect); $this->authenticateAndRedirect($login, $password, false, $urlToRedirect); }
/** * Returns an array containing the following information: * - referer_type * - direct -- absence of referer URL OR referer URL has the same host * - site -- based on the referer URL * - search_engine -- based on the referer URL * - campaign -- based on campaign URL parameter * * - referer_name * - () * - piwik.net -- site host name * - google.fr -- search engine host name * - adwords-search -- campaign name * * - referer_keyword * - () * - () * - my keyword * - my paid keyword * - () * - () * * - referer_url : the same for all the referer types * * @param $refererUrl must be URL Encoded * @param $currentUrl * @param $idSite * @return array */ public function getRefererInformation($refererUrl, $currentUrl, $idSite) { $this->idsite = $idSite; // default values for the referer_* fields $refererUrl = Piwik_Common::unsanitizeInputValue($refererUrl); if (!empty($refererUrl) && !Piwik_Common::isLookLikeUrl($refererUrl)) { $refererUrl = ''; } $currentUrl = Piwik_Tracker_Action::cleanupUrl($currentUrl); $this->refererUrl = $refererUrl; $this->refererUrlParse = @parse_url($this->refererUrl); $this->currentUrlParse = @parse_url($currentUrl); $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_DIRECT_ENTRY; $this->nameRefererAnalyzed = ''; $this->keywordRefererAnalyzed = ''; $this->refererHost = ''; if (isset($this->refererUrlParse['host'])) { $this->refererHost = $this->refererUrlParse['host']; } $refererDetected = false; if (!empty($this->currentUrlParse['host']) && $this->detectRefererCampaign()) { $refererDetected = true; } if (!$refererDetected) { if ($this->detectRefererDirectEntry() || $this->detectRefererSearchEngine()) { $refererDetected = true; } } if (!empty($this->refererHost) && !$refererDetected) { $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_WEBSITE; $this->nameRefererAnalyzed = mb_strtolower($this->refererHost, 'UTF-8'); } $refererInformation = array('referer_type' => $this->typeRefererAnalyzed, 'referer_name' => $this->nameRefererAnalyzed, 'referer_keyword' => $this->keywordRefererAnalyzed, 'referer_url' => $this->refererUrl); return $refererInformation; }
/** * Updates a user in the database. * Only login and password are required (case when we update the password). * When the password changes, the key token for this user will change, which could break * its API calls. * * @see addUser() for all the parameters */ public function updateUser($userLogin, $password = false, $email = false, $alias = false) { Piwik::checkUserIsSuperUserOrTheUser($userLogin); $this->checkUserIsNotAnonymous($userLogin); $this->checkUserIsNotSuperUser($userLogin); $userInfo = $this->getUser($userLogin); if (empty($password)) { $password = $userInfo['password']; } else { $password = Piwik_Common::unsanitizeInputValue($password); $this->checkPassword($password); $password = $this->getCleanPassword($password); } if (empty($alias)) { $alias = $userInfo['alias']; } if (empty($email)) { $email = $userInfo['email']; } if ($email != $userInfo['email']) { $this->checkEmail($email); } $alias = $this->getCleanAlias($alias, $userLogin); $token_auth = $this->getTokenAuth($userLogin, $password); $db = Zend_Registry::get('db'); $db->update(Piwik_Common::prefixTable("user"), array('password' => $password, 'alias' => $alias, 'email' => $email, 'token_auth' => $token_auth), "login = '******'"); Piwik_Common::deleteTrackerCache(); Piwik_PostEvent('UsersManager.updateUser', $userLogin); }
public static function cleanupUrl($url) { $url = Piwik_Common::unsanitizeInputValue($url); $url = self::cleanupString($url); $url = self::convertMatrixUrl($url); return $url; }
private function formatText($text) { return Piwik_Common::unsanitizeInputValue($text); }
/** * Given an API report to query (eg. "Referers.getKeywords", and a Label (eg. "free%20software"), * this function will query the API for the previous days/weeks/etc. and will return * a ready to use data structure containing the metrics for the requested Label, along with enriched information (min/max values, etc.) * * @return array */ public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $column = false, $language = false, $idGoal = false, $legendAppendMetric = true, $labelUseAbsoluteUrl = true) { // validation of requested $period & $date if ($period == 'range') { // load days in the range $period = 'day'; } if (!Piwik_Archive::isMultiplePeriod($date, $period)) { throw new Exception("Row evolutions can not be processed with this combination of \\'date\\' and \\'period\\' parameters."); } // this is needed because Piwik_API_Proxy uses Piwik_Common::getRequestVar which in turn // uses Piwik_Common::sanitizeInputValue. This causes the > that separates recursive labels // to become > and we need to undo that here. $label = Piwik_Common::unsanitizeInputValue($label); if ($label) { $labels = explode(',', $label); $labels = array_unique($labels); } else { $range = new Piwik_Period_Range($period, $date); $lastDate = $range->getDateEnd(); // retrieve top labels for the most recent period $mostRecentDataTable = $this->loadRowEvolutionDataFromAPI($idSite, $period, $lastDate, $apiModule, $apiAction, null, $segment, $idGoal); $labels = $mostRecentDataTable->getColumn('label'); //@review $labelCount can be equal to 0, this means there are no data what should this API return in that case? if (!count($labels)) { return null; } } if (count($labels) > 1) { $data = $this->getMultiRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $column, $language, $idGoal, $legendAppendMetric, $labelUseAbsoluteUrl); } else { $data = $this->getSingleRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels[0], $segment, $language, $idGoal, $labelUseAbsoluteUrl); } return $data; }
function Piwik_Form_fieldHaveSameValue($element, $value, $arg) { $value2 = Piwik_Common::getRequestVar($arg, '', 'string'); $value2 = Piwik_Common::unsanitizeInputValue($value2); return $value === $value2; }
/** * Derive the action ID from the request action name and type. */ private function deriveIdAction($actionName, $actionType) { $actionsPlugin = new Piwik_Actions(); switch ($actionType) { case 'url': $originalActionName = $actionName; $actionName = Piwik_Common::unsanitizeInputValue($actionName); $id = $actionsPlugin->getIdActionFromSegment($actionName, 'idaction_url'); if ($id < 0) { // an example where this is needed is urls containing < or > $actionName = $originalActionName; $id = $actionsPlugin->getIdActionFromSegment($actionName, 'idaction_url'); } return $id; case 'title': $id = $actionsPlugin->getIdActionFromSegment($actionName, 'idaction_name'); if ($id < 0) { $unkown = Piwik_Actions_ArchivingHelper::getUnknownActionName(Piwik_Tracker_Action::TYPE_ACTION_NAME); if (trim($actionName) == trim($unkown)) { $id = $actionsPlugin->getIdActionFromSegment('', 'idaction_name'); } } return $id; default: throw new Exception('Unknown action type'); } }
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; } }
/** * @param $action * @return bool true if the outlink the visitor clicked on points to one of the known hosts for this website */ protected function detectActionIsOutlinkOnAliasHost(Piwik_Tracker_Action_Interface $action) { if ($action->getActionType() != Piwik_Tracker_Action_Interface::TYPE_OUTLINK) { return false; } $actionUrl = $action->getActionUrl(); $actionUrlParsed = @parse_url(Piwik_Common::unsanitizeInputValue($actionUrl)); if (!isset($actionUrlParsed['host'])) { return false; } return $this->isHostKnownAliasHost($actionUrlParsed['host']); }
/** * Handles the given data table * * @param Piwik_DataTable $datatable * @return string */ protected function handleDataTable($datatable) { // if requested, flatten nested tables if (Piwik_Common::getRequestVar('flat', '0', 'string', $this->request) == '1') { $flattener = new Piwik_API_DataTableManipulator_Flattener($this->apiModule, $this->apiMethod, $this->request); if (Piwik_Common::getRequestVar('include_aggregate_rows', '0', 'string', $this->request) == '1') { $flattener->includeAggregateRows(); } $datatable = $flattener->flatten($datatable); } // if the flag disable_generic_filters is defined we skip the generic filters if (0 == Piwik_Common::getRequestVar('disable_generic_filters', '0', 'string', $this->request)) { $genericFilter = new Piwik_API_DataTableGenericFilter($this->request); $genericFilter->filter($datatable); } // we automatically safe decode all datatable labels (against xss) $datatable->queueFilter('SafeDecodeLabel'); // if the flag disable_queued_filters is defined we skip the filters that were queued if (Piwik_Common::getRequestVar('disable_queued_filters', 'false', 'string', $this->request) == 'false') { $datatable->applyQueuedFilters(); } // use the ColumnDelete filter if hideColumns/showColumns is provided (must be done // after queued filters are run so processed metrics can be removed, too) $hideColumns = Piwik_Common::getRequestVar('hideColumns', '', 'string', $this->request); $showColumns = Piwik_Common::getRequestVar('showColumns', '', 'string', $this->request); if ($hideColumns !== '' || $showColumns !== '') { $datatable->filter('ColumnDelete', array($hideColumns, $showColumns)); } // apply label filter: only return a single row matching the label parameter $label = Piwik_Common::getRequestVar('label', '', 'string', $this->request); if ($label !== '') { $label = Piwik_Common::unsanitizeInputValue($label); $filter = new Piwik_API_DataTableManipulator_LabelFilter($this->apiModule, $this->apiMethod, $this->request); $datatable = $filter->filter($label, $datatable); } return $this->getRenderedDataTable($datatable); }
static public function excludeQueryParametersFromUrl($originalUrl, $idSite) { $website = Piwik_Common::getCacheWebsiteAttributes( $idSite ); $originalUrl = Piwik_Common::unsanitizeInputValue($originalUrl); $originalUrl = self::cleanupString($originalUrl); $parsedUrl = @parse_url($originalUrl); if(empty($parsedUrl['query'])) { return $originalUrl; } $campaignTrackingParameters = Piwik_Common::getCampaignParameters(); $campaignTrackingParameters = array_merge( $campaignTrackingParameters[0], // campaign name parameters $campaignTrackingParameters[1] // campaign keyword parameters ); $excludedParameters = isset($website['excluded_parameters']) ? $website['excluded_parameters'] : array(); $parametersToExclude = array_merge( $excludedParameters, self::$queryParametersToExclude, $campaignTrackingParameters); $parametersToExclude = array_map('strtolower', $parametersToExclude); $queryParameters = Piwik_Common::getArrayFromQueryString($parsedUrl['query']); $validQuery = ''; $separator = '&'; foreach($queryParameters as $name => $value) { if(!in_array(strtolower($name), $parametersToExclude)) { if (is_array($value)) { foreach ($value as $param) { if($param === false) { $validQuery .= $name.'[]'.$separator; } else { $validQuery .= $name.'[]='.$param.$separator; } } } else if($value === false) { $validQuery .= $name.$separator; } else { $validQuery .= $name.'='.$value.$separator; } } } $parsedUrl['query'] = substr($validQuery,0,-strlen($separator)); $url = Piwik_Common::getParseUrlReverse($parsedUrl); printDebug('Excluding parameters "'.implode(',',$excludedParameters).'" from URL'); if($originalUrl != $url) { printDebug(' Before was "'.$originalUrl.'"'); printDebug(' After is "'.$url.'"'); } return $url; }
protected function initChartObjectData() { // if the loaded datatable is a simple DataTable, it is most likely a plugin plotting some custom data // we don't expect plugin developers to return a well defined Piwik_DataTable_Array if ($this->dataTable instanceof Piwik_DataTable) { return parent::initChartObjectData(); } $this->dataTable->applyQueuedFilters(); if (!$this->dataTable instanceof Piwik_DataTable_Array) { throw new Exception("Expecting a DataTable_Array with custom format to draw an evolution chart"); } // the X label is extracted from the 'period' object in the table's metadata $xLabels = $uniqueIdsDataTable = array(); foreach ($this->dataTable->metadata as $idDataTable => $metadataDataTable) { //eg. "Aug 2009" $xLabels[] = $metadataDataTable['period']->getLocalizedShortString(); // we keep track of all unique data table that we need to set a Y value for $uniqueIdsDataTable[] = $idDataTable; } $idSite = Piwik_Common::getRequestVar('idSite', null, 'int'); $requestedColumnNames = $this->getColumnsToDisplay(); $units = $this->getUnitsForColumnsToDisplay(); $yAxisLabelToUnit = array(); $yAxisLabelToValue = array(); foreach ($this->dataTable->getArray() as $idDataTable => $dataTable) { foreach ($dataTable->getRows() as $row) { $rowLabel = $row->getColumn('label'); // put together configuration for row picker. // do this for every data table in the array because rows do not // have to present for each date. if ($this->rowPicker !== false) { $rowVisible = $this->handleRowForRowPicker($rowLabel); if (!$rowVisible) { continue; } } // build data for request columns foreach ($requestedColumnNames as $requestedColumnName) { $yAxisLabel = $this->getSeriesLabel($rowLabel, $requestedColumnName); if (($columnValue = $row->getColumn($requestedColumnName)) !== false) { $yAxisLabelToValue[$yAxisLabel][$idDataTable] = $columnValue; $yAxisLabelToUnit[$yAxisLabel] = $units[$requestedColumnName]; } } } } // make sure all column values are set to at least zero (no gap in the graph) $yAxisLabelToValueCleaned = array(); foreach ($uniqueIdsDataTable as $uniqueIdDataTable) { foreach ($yAxisLabelToValue as $yAxisLabel => $idDataTableToColumnValue) { if (isset($idDataTableToColumnValue[$uniqueIdDataTable])) { $columnValue = $idDataTableToColumnValue[$uniqueIdDataTable]; } else { $columnValue = 0; } $yAxisLabelToValueCleaned[$yAxisLabel][] = $columnValue; } } $this->view->setAxisXLabels($xLabels); $this->view->setAxisYValues($yAxisLabelToValueCleaned); $this->view->setAxisYUnits($yAxisLabelToUnit); $countGraphElements = $this->dataTable->getRowsCount(); $firstDatatable = reset($this->dataTable->metadata); $period = $firstDatatable['period']; switch ($period->getLabel()) { case 'day': $steps = 7; break; case 'week': $steps = 10; break; case 'month': $steps = 6; break; case 'year': $steps = 2; break; default: $steps = 10; break; } // For Custom Date Range, when the number of elements plotted can be small, make sure the X legend is useful if ($countGraphElements <= 20) { $steps = 2; } $this->view->setXSteps($steps); if ($this->isLinkEnabled()) { $axisXOnClick = array(); $queryStringAsHash = $this->getQueryStringAsHash(); foreach ($this->dataTable->metadata as $idDataTable => $metadataDataTable) { $period = $metadataDataTable['period']; $dateInUrl = $period->getDateStart(); $parameters = array('idSite' => $idSite, 'period' => $period->getLabel(), 'date' => $dateInUrl->toString(), 'segment' => Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar('segment', false))); $hash = ''; if (!empty($queryStringAsHash)) { $hash = '#' . Piwik_Url::getQueryStringFromParameters($queryStringAsHash + $parameters); } $link = 'index.php?' . Piwik_Url::getQueryStringFromParameters(array('module' => 'CoreHome', 'action' => 'index') + $parameters) . $hash; $axisXOnClick[] = $link; } $this->view->setAxisXOnClick($axisXOnClick); } $this->addSeriesPickerToView(); if ($this->rowPicker !== false) { // configure the row picker $this->view->setSelectableRows(array_values($this->rowPickerConfig)); } }
/** * Get information about the evolution of a row in any report. * * @return array */ public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label, $segment = false, $column = false, $language = false) { // this is needed because Piwik_API_Proxy uses Piwik_Common::getRequestVar which in turn // uses Piwik_Common::sanitizeInputValue. This causes the > that separates recursive labels // to become > and we need to undo that here. $label = Piwik_Common::unsanitizeInputValue($label); $labels = explode(',', $label); $labels = array_map('urldecode', $labels); if (count($labels) > 1) { return $this->getMultiRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $column, $language); } else { return $this->getSingleRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels[0], $segment, $language); } }
/** * Records settings from the "User Settings" page */ public function recordUserSettings() { $response = new Piwik_API_ResponseBuilder(Piwik_Common::getRequestVar('format')); try { $this->checkTokenInUrl(); $alias = Piwik_Common::getRequestVar('alias'); $email = Piwik_Common::getRequestVar('email'); $defaultReport = Piwik_Common::getRequestVar('defaultReport'); $defaultDate = Piwik_Common::getRequestVar('defaultDate'); $newPassword = false; $password = Piwik_Common::getRequestvar('password', false); $passwordBis = Piwik_Common::getRequestvar('passwordBis', false); if(!empty($password) || !empty($passwordBis)) { if($password != $passwordBis) { throw new Exception(Piwik_Translate('Login_PasswordsDoNotMatch')); } $newPassword = $password; } $userLogin = Piwik::getCurrentUserLogin(); if(Piwik::isUserIsSuperUser()) { $superUser = Zend_Registry::get('config')->superuser; $updatedSuperUser = false; if($newPassword !== false) { $newPassword = Piwik_Common::unsanitizeInputValue($newPassword); $md5PasswordSuperUser = md5($newPassword); $superUser->password = $md5PasswordSuperUser; $updatedSuperUser = true; } if($superUser->email != $email) { $superUser->email = $email; $updatedSuperUser = true; } if($updatedSuperUser) { Zend_Registry::get('config')->superuser = $superUser->toArray(); } } else { Piwik_UsersManager_API::getInstance()->updateUser($userLogin, $newPassword, $email, $alias); if($newPassword !== false) { $newPassword = Piwik_Common::unsanitizeInputValue($newPassword); } } // logs the user in with the new password if($newPassword !== false) { $info = array( 'login' => $userLogin, 'md5Password' => md5($newPassword), 'rememberMe' => false, ); Piwik_PostEvent('Login.initSession', $info); } Piwik_UsersManager_API::getInstance()->setUserPreference($userLogin, Piwik_UsersManager_API::PREFERENCE_DEFAULT_REPORT, $defaultReport); Piwik_UsersManager_API::getInstance()->setUserPreference($userLogin, Piwik_UsersManager_API::PREFERENCE_DEFAULT_REPORT_DATE, $defaultDate); $toReturn = $response->getResponse(); } catch(Exception $e ) { $toReturn = $response->getResponseException( $e ); } echo $toReturn; }
/** * Returns Items read from the request string * @return array|false */ protected function getEcommerceItemsFromRequest() { $items = Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar('ec_items', '', 'string', $this->request)); if (empty($items)) { printDebug("There are no Ecommerce items in the request"); // we still record an Ecommerce order without any item in it return array(); } $items = Piwik_Common::json_decode($items, $assoc = true); if (!is_array($items)) { printDebug("Error while json_decode the Ecommerce items = " . var_export($items, true)); return false; } $cleanedItems = $this->getCleanedEcommerceItems($items); return $cleanedItems; }
/** Logger hook: log number of results, if available */ public function logResults($notification) { $action = $notification->getNotificationObject(); $idaction = $action->getIdActionUrl(); // load site config from tracker cache $info = $notification->getNotificationInfo(); $idsite = $info['idSite']; $site = Piwik_Common::getCacheWebsiteAttributes($idsite); $site['idsite'] = $idsite; // search results passed via JS tracker $data = Piwik_Common::getRequestVar('data', ''); $data = Piwik_Common::unsanitizeInputValue($data); $data = json_decode($data, true); $resultCount = false; if (isset($data['SiteSearch_Results'])) { $resultCount = intval($data['SiteSearch_Results']); } if (!empty($site['sitesearch_url']) && !empty($site['sitesearch_parameter'])) { // check whether action is a site search $url = preg_quote($site['sitesearch_url'], '/'); $param = preg_quote($site['sitesearch_parameter'], '/'); $regex = '/' . $url . '(.*)(&|\\?)' . $param . '=(.*?)(&|$)/i'; $actionUrl = $action->getActionUrl(); if (preg_match($regex, $actionUrl, $matches)) { require_once PIWIK_INCLUDE_PATH . '/plugins/SiteSearch/Archive.php'; require_once PIWIK_INCLUDE_PATH . '/plugins/SiteSearch/Db.php'; Piwik_SiteSearch_Archive::logAction(array('idaction' => $idaction, 'name' => $actionUrl), $site['idsite'], $site, $resultCount); } } }