public function setAxisYValues(&$values) { foreach ($values as $label => &$data) { $this->series[] = array('label' => $label, 'internalLabel' => $label); array_walk($data, function (&$v) { $v = (double) Common::forceDotAsSeparatorForDecimalPoint($v); }); $this->data[] =& $data; } }
private static function getOptions($type) { $options = self::getBackendOptions($type); switch ($type) { case 'file': $options = array('directory' => StaticContainer::get('path.cache')); break; case 'chained': foreach ($options['backends'] as $backend) { $options[$backend] = self::getOptions($backend); } break; case 'redis': if (!empty($options['timeout'])) { $options['timeout'] = (double) Common::forceDotAsSeparatorForDecimalPoint($options['timeout']); } break; } return $options; }
/** * @depends testApi * @dataProvider getAnotherApiForTesting */ public function testAnotherApi($api, $params) { // Get the top segment value $request = new Request('method=API.getSuggestedValuesForSegment' . '&segmentName=' . $params['segmentToComplete'] . '&idSite=' . $params['idSite'] . '&format=php&serialize=0'); $response = $request->process(); $this->assertApiResponseHasNoError($response); $topSegmentValue = @$response[0]; if ($topSegmentValue !== false && !is_null($topSegmentValue)) { if (is_numeric($topSegmentValue) || is_float($topSegmentValue) || preg_match('/^\\d*?,\\d*$/', $topSegmentValue)) { $topSegmentValue = Common::forceDotAsSeparatorForDecimalPoint($topSegmentValue); } // Now build the segment request $segmentValue = rawurlencode(html_entity_decode($topSegmentValue)); $params['segment'] = $params['segmentToComplete'] . '==' . $segmentValue; unset($params['segmentToComplete']); $this->runApiTests($api, $params); self::$processed++; } else { self::$skipped[] = $params['segmentToComplete']; } }
public function triggerAlert($idAlert, $idSite, $valueNew, $valueOld, $datetime) { $alert = $this->getAlert($idAlert); $keysToKeep = array('idalert', 'name', 'login', 'period', 'metric', 'metric_condition', 'metric_matched', 'report', 'report_condition', 'report_matched', 'compared_to', 'email_me', 'additional_emails', 'phone_numbers'); $triggeredAlert = array(); foreach ($keysToKeep as $key) { $triggeredAlert[$key] = $alert[$key]; } $triggeredAlert['metric_matched'] = Common::forceDotAsSeparatorForDecimalPoint($triggeredAlert['metric_matched']); $triggeredAlert['ts_triggered'] = $datetime; $triggeredAlert['ts_last_sent'] = null; $triggeredAlert['value_new'] = $valueNew; $triggeredAlert['value_old'] = $valueOld; $triggeredAlert['idsite'] = $idSite; $triggeredAlert['additional_emails'] = json_encode($triggeredAlert['additional_emails']); $triggeredAlert['phone_numbers'] = json_encode($triggeredAlert['phone_numbers']); $db = $this->getDb(); $db->insert(Common::prefixTable('alert_triggered'), $triggeredAlert); }
/** * Caches a single numeric record in the archive for this processor's site, period and * segment. * * Numeric values are not inserted if they equal `0`. * * @param string $name The name of the numeric value, eg, `'Referrers_distinctKeywords'`. * @param float $value The numeric value. * @api */ public function insertNumericRecord($name, $value) { $value = round($value, 2); $value = Common::forceDotAsSeparatorForDecimalPoint($value); $this->archiveWriter->insertRecord($name, $value); }
/** * Records in the DB the association between the visit and this action. * * @param int $idReferrerActionUrl is the ID of the last action done by the current visit. * @param $idReferrerActionName * @param Visitor $visitor */ public function record(Visitor $visitor, $idReferrerActionUrl, $idReferrerActionName) { $this->loadIdsFromLogActionTable(); $visitAction = array('idvisit' => $visitor->getVisitorColumn('idvisit'), 'idsite' => $this->request->getIdSite(), 'idvisitor' => $visitor->getVisitorColumn('idvisitor'), 'idaction_url' => $this->getIdActionUrl(), 'idaction_url_ref' => $idReferrerActionUrl, 'idaction_name_ref' => $idReferrerActionName); /** @var ActionDimension[] $dimensions */ $dimensions = ActionDimension::getAllDimensions(); foreach ($dimensions as $dimension) { $value = $dimension->onNewAction($this->request, $visitor, $this); if ($value !== false) { if (is_float($value)) { $value = Common::forceDotAsSeparatorForDecimalPoint($value); } $visitAction[$dimension->getColumnName()] = $value; } } // idaction_name is NULLable. we only set it when applicable if ($this->isActionHasActionName()) { $visitAction['idaction_name'] = (int) $this->getIdActionName(); } foreach ($this->actionIdsCached as $field => $idAction) { $visitAction[$field] = $idAction === false ? 0 : $idAction; } $customValue = $this->getCustomFloatValue(); if (!empty($customValue)) { $visitAction[self::DB_COLUMN_CUSTOM_FLOAT] = Common::forceDotAsSeparatorForDecimalPoint($customValue); } $visitAction = array_merge($visitAction, $this->customFields); $this->idLinkVisitAction = $this->getModel()->createAction($visitAction); $visitAction['idlink_va'] = $this->idLinkVisitAction; Common::printDebug("Inserted new action:"); $visitActionDebug = $visitAction; $visitActionDebug['idvisitor'] = bin2hex($visitActionDebug['idvisitor']); Common::printDebug($visitActionDebug); /** * Triggered after successfully persisting a [visit action entity](/guides/persistence-and-the-mysql-backend#visit-actions). * * This event is deprecated, use [Dimensions](http://developer.piwik.org/guides/dimensions) instead. * * @param Action $tracker Action The Action tracker instance. * @param array $visitAction The visit action entity that was persisted. Read * [this](/guides/persistence-and-the-mysql-backend#visit-actions) to see what it contains. * @deprecated */ Piwik::postEvent('Tracker.recordAction', array($trackerAction = $this, $visitAction)); }
/** * Updates a Goal description. * Will not update or re-process the conversions already recorded * * @see addGoal() for parameters description * @param int $idSite * @param int $idGoal * @param $name * @param $matchAttribute * @param string $pattern * @param string $patternType * @param bool $caseSensitive * @param bool|float $revenue * @param bool $allowMultipleConversionsPerVisit * @return void */ public function updateGoal($idSite, $idGoal, $name, $matchAttribute, $pattern, $patternType, $caseSensitive = false, $revenue = false, $allowMultipleConversionsPerVisit = false) { Piwik::checkUserHasAdminAccess($idSite); $name = $this->checkName($name); $pattern = $this->checkPattern($pattern); $this->checkPatternIsValid($patternType, $pattern, $matchAttribute); $revenue = Common::forceDotAsSeparatorForDecimalPoint((double) $revenue); $this->getModel()->updateGoal($idSite, $idGoal, array('name' => $name, 'match_attribute' => $matchAttribute, 'pattern' => $pattern, 'pattern_type' => $patternType, 'case_sensitive' => (int) $caseSensitive, 'allow_multiple' => (int) $allowMultipleConversionsPerVisit, 'revenue' => $revenue)); $this->getGoalsInfoStaticCache()->delete(self::getCacheId($idSite)); Cache::regenerateCacheWebsiteAttributes($idSite); }
/** * Edits an Alert for given website(s). * * @param $idAlert * @param string $name Name of Alert * @param mixed $idSites Single int or array of ints of idSites. * @param string $period Period the alert is defined on. * @param bool $emailMe * @param array $additionalEmails * @param array $phoneNumbers * @param string $metric (nb_uniq_visits, sum_visit_length, ..) * @param string $metricCondition * @param float $metricValue * @param string $reportUniqueId * @param int $comparedTo * @param bool|string $reportCondition * @param bool|string $reportValue * * @internal param bool $enableEmail * @return boolean */ public function editAlert($idAlert, $name, $idSites, $period, $emailMe, $additionalEmails, $phoneNumbers, $metric, $metricCondition, $metricValue, $comparedTo, $reportUniqueId, $reportCondition = false, $reportValue = false) { // make sure alert exists and user has permission to read $this->getAlert($idAlert); $idSites = Site::getIdSitesFromIdSitesString($idSites); $additionalEmails = $this->filterAdditionalEmails($additionalEmails); $phoneNumbers = $this->filterPhoneNumbers($phoneNumbers); $this->checkAlert($idSites, $name, $period, $additionalEmails, $metricCondition, $metric, $comparedTo, $reportCondition, $reportUniqueId); $name = Common::unsanitizeInputValue($name); if (empty($reportCondition) || empty($reportValue)) { $reportCondition = null; $reportValue = null; } $metricValue = Common::forceDotAsSeparatorForDecimalPoint((double) $metricValue); return $this->getModel()->updateAlert($idAlert, $name, $idSites, $period, $emailMe, $additionalEmails, $phoneNumbers, $metric, $metricCondition, $metricValue, $comparedTo, $reportUniqueId, $reportCondition, $reportValue); }
/** * When destroyed, if SQL profiled enabled, logs the SQL profiling information */ public function recordProfiling() { if (is_null($this->connection)) { return; } // turn off the profiler so we don't profile the following queries self::$profiling = false; $LogProfiling = Factory::getDAO('log_profiling', $this->connection); foreach ($this->queriesProfiling as $query => $info) { $time = $info['sum_time_ms']; $time = Common::forceDotAsSeparatorForDecimalPoint($time); $count = $info['count']; $LogProfiling->recordProfiling($query, $count, $time); } // turn back on profiling self::$profiling = true; }
/** * Gets a sanitized request parameter by name from the `$_GET` and `$_POST` superglobals. * * Use this function to get request parameter values. **_NEVER use `$_GET` and `$_POST` directly._** * * If the variable cannot be found, and a default value was not provided, an exception is raised. * * _See {@link sanitizeInputValues()} to learn more about sanitization._ * * @param string $varName Name of the request parameter to get. By default, we look in `$_GET[$varName]` * and `$_POST[$varName]` for the value. * @param string|null $varDefault The value to return if the request parameter cannot be found or has an empty value. * @param string|null $varType Expected type of the request variable. This parameters value must be one of the following: * `'array'`, `'int'`, `'integer'`, `'string'`, `'json'`. * * If `'json'`, the string value will be `json_decode`-d and then sanitized. * @param array|null $requestArrayToUse The array to use instead of `$_GET` and `$_POST`. * @throws Exception If the request parameter doesn't exist and there is no default value, or if the request parameter * exists but has an incorrect type. * @return mixed The sanitized request parameter. * @api */ public static function getRequestVar($varName, $varDefault = null, $varType = null, $requestArrayToUse = null) { if (is_null($requestArrayToUse)) { $requestArrayToUse = $_GET + $_POST; } $varDefault = self::sanitizeInputValues($varDefault); if ($varType === 'int') { // settype accepts only integer // 'int' is simply a shortcut for 'integer' $varType = 'integer'; } // there is no value $varName in the REQUEST so we try to use the default value if (empty($varName) || !isset($requestArrayToUse[$varName]) || !is_array($requestArrayToUse[$varName]) && strlen($requestArrayToUse[$varName]) === 0) { if (is_null($varDefault)) { throw new Exception("The parameter '{$varName}' isn't set in the Request, and a default value wasn't provided."); } else { if (!is_null($varType) && in_array($varType, array('string', 'integer', 'array'))) { settype($varDefault, $varType); } return $varDefault; } } // Normal case, there is a value available in REQUEST for the requested varName: // we deal w/ json differently if ($varType == 'json') { $value = self::undoMagicQuotes($requestArrayToUse[$varName]); $value = json_decode($value, $assoc = true); return self::sanitizeInputValues($value, $alreadyStripslashed = true); } $value = self::sanitizeInputValues($requestArrayToUse[$varName]); if (isset($varType)) { $ok = false; if ($varType === 'string') { if (is_string($value) || is_int($value)) { $ok = true; } else { if (is_float($value)) { $value = Common::forceDotAsSeparatorForDecimalPoint($value); $ok = true; } } } elseif ($varType === 'integer') { if ($value == (string) (int) $value) { $ok = true; } } elseif ($varType === 'float') { $valueToCompare = (string) (double) $value; $valueToCompare = Common::forceDotAsSeparatorForDecimalPoint($valueToCompare); if ($value == $valueToCompare) { $ok = true; } } elseif ($varType === 'array') { if (is_array($value)) { $ok = true; } } else { throw new Exception("\$varType specified is not known. It should be one of the following: array, int, integer, float, string"); } // The type is not correct if ($ok === false) { if ($varDefault === null) { throw new Exception("The parameter '{$varName}' doesn't have a correct type, and a default value wasn't provided."); } else { settype($varDefault, $varType); return $varDefault; } } settype($value, $varType); } return $value; }
/** * Encode HTML entities * * @param mixed $values * @return mixed */ protected function encodeValues(&$values) { if (is_array($values)) { foreach ($values as &$value) { $value = $this->encodeValues($value); } } elseif (is_float($values)) { $values = Common::forceDotAsSeparatorForDecimalPoint($values); } elseif (is_string($values)) { $values = htmlentities($values, ENT_COMPAT, 'UTF-8'); $values = str_replace('$', '$', $values); } return $values; }
/** * @param ConversionDimension[] $dimensions * @param string $hook * @param Visitor $visitor * @param Action|null $action * @param array|null $valuesToUpdate If null, $this->visitorInfo will be updated * * @return array|null The updated $valuesToUpdate or null if no $valuesToUpdate given */ private function triggerHookOnDimensions($dimensions, $hook, $visitor, $action, $valuesToUpdate) { foreach ($dimensions as $dimension) { $value = $dimension->{$hook}($this->request, $visitor, $action, $this); if (false !== $value) { if (is_float($value)) { $value = Common::forceDotAsSeparatorForDecimalPoint($value); } $fieldName = $dimension->getColumnName(); $visitor->setVisitorColumn($fieldName, $value); $valuesToUpdate[$fieldName] = $value; } } return $valuesToUpdate; }
/** * When destroyed, if SQL profiled enabled, logs the SQL profiling information */ public function recordProfiling() { if (is_null($this->connection)) { return; } // turn off the profiler so we don't profile the following queries self::$profiling = false; foreach ($this->queriesProfiling as $query => $info) { $time = $info['sum_time_ms']; $time = Common::forceDotAsSeparatorForDecimalPoint($time); $count = $info['count']; $queryProfiling = "INSERT INTO " . Common::prefixTable('log_profiling') . "\n\t\t\t\t\t\t(query,count,sum_time_ms) VALUES (?,{$count},{$time})\n\t\t\t\t\t\tON DUPLICATE KEY UPDATE count=count+{$count},sum_time_ms=sum_time_ms+{$time}"; $this->query($queryProfiling, array($query)); } // turn back on profiling self::$profiling = true; }
public function getPrettyTimeFromSeconds($numberOfSeconds, $displayTimeAsSentence = false, $round = false) { return $round ? (int) $numberOfSeconds : (double) Common::forceDotAsSeparatorForDecimalPoint($numberOfSeconds); }
/** * @param VisitDimension[] $dimensions * @param string $hook * @param Visitor $visitor * @param Action|null $action * @param array|null $valuesToUpdate If null, $this->visitorInfo will be updated * * @return array|null The updated $valuesToUpdate or null if no $valuesToUpdate given */ private function triggerHookOnDimensions($dimensions, $hook, $valuesToUpdate = null) { $visitor = $this->makeVisitorFacade(); /** @var Action $action */ $action = $this->request->getMetadata('Actions', 'action'); foreach ($dimensions as $dimension) { $value = $dimension->{$hook}($this->request, $visitor, $action); if ($value !== false) { $fieldName = $dimension->getColumnName(); $visitor->setVisitorColumn($fieldName, $value); if (is_float($value)) { $value = Common::forceDotAsSeparatorForDecimalPoint($value); } if ($valuesToUpdate !== null) { $valuesToUpdate[$fieldName] = $value; } else { $this->visitProperties->setProperty($fieldName, $value); } } } return $valuesToUpdate; }
/** * Returns a percent string from a quotient value. Forces the use of a '.' * decimal place. * * @param float $value * @return string * @api */ public function getPrettyPercentFromQuotient($value) { $result = $value * 100 . '%'; return Common::forceDotAsSeparatorForDecimalPoint($result); }
private function getTimezonesListUTCOffsets() { // manually add the UTC offsets $GmtOffsets = array(-12, -11.5, -11, -10.5, -10, -9.5, -9, -8.5, -8, -7.5, -7, -6.5, -6, -5.5, -5, -4.5, -4, -3.5, -3, -2.5, -2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 5.75, 6, 6.5, 7, 7.5, 8, 8.5, 8.75, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.75, 13, 13.75, 14); $return = array(); foreach ($GmtOffsets as $offset) { $offset = Common::forceDotAsSeparatorForDecimalPoint($offset); if ($offset > 0) { $offset = '+' . $offset; } elseif ($offset == 0) { $offset = ''; } $offset = 'UTC' . $offset; $offsetName = str_replace(array('.25', '.5', '.75'), array(':15', ':30', ':45'), $offset); $return[$offset] = $offsetName; } return $return; }
/** * Calculates and formats a quotient based on a divisor and dividend. * * Unlike ColumnCallbackAddColumnPercentage's, * version of this method, this method will return 100% if the past * value of a metric is 0, and the current value is not 0. For a * value representative of an evolution, this makes sense. * * @param int|float $value The dividend. * @param int|float $divisor * @return string */ protected function formatValue($value, $divisor) { $value = self::getPercentageValue($value, $divisor, $this->quotientPrecision); $value = self::appendPercentSign($value); $value = Common::forceDotAsSeparatorForDecimalPoint($value); return $value; }
/** * Records in the DB the association between the visit and this action. * * @param int $idReferrerActionUrl is the ID of the last action done by the current visit. * @param $idReferrerActionName * @param Visitor $visitor */ public function record(Visitor $visitor, $idReferrerActionUrl, $idReferrerActionName) { $this->loadIdsFromLogActionTable(); $visitAction = array('idvisit' => $visitor->getVisitorColumn('idvisit'), 'idsite' => $this->request->getIdSite(), 'idvisitor' => $visitor->getVisitorColumn('idvisitor'), 'idaction_url' => $this->getIdActionUrl(), 'idaction_url_ref' => $idReferrerActionUrl, 'idaction_name_ref' => $idReferrerActionName); /** @var ActionDimension[] $dimensions */ $dimensions = ActionDimension::getAllDimensions(); foreach ($dimensions as $dimension) { $value = $dimension->onNewAction($this->request, $visitor, $this); if ($value !== false) { if (is_float($value)) { $value = Common::forceDotAsSeparatorForDecimalPoint($value); } $visitAction[$dimension->getColumnName()] = $value; } } // idaction_name is NULLable. we only set it when applicable if ($this->isActionHasActionName()) { $visitAction['idaction_name'] = (int) $this->getIdActionName(); } foreach ($this->actionIdsCached as $field => $idAction) { $visitAction[$field] = $idAction === false ? 0 : $idAction; } $customValue = $this->getCustomFloatValue(); if (!empty($customValue)) { $visitAction[self::DB_COLUMN_CUSTOM_FLOAT] = Common::forceDotAsSeparatorForDecimalPoint($customValue); } $visitAction = array_merge($visitAction, $this->customFields); $this->idLinkVisitAction = $this->getModel()->createAction($visitAction); $visitAction['idlink_va'] = $this->idLinkVisitAction; Common::printDebug("Inserted new action:"); $visitActionDebug = $visitAction; $visitActionDebug['idvisitor'] = bin2hex($visitActionDebug['idvisitor']); Common::printDebug($visitActionDebug); }