Teknik is a suite of services with attractive and functional interfaces. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MetricsFormatter.php 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik;
  10. use Piwik\Tracker\GoalManager;
  11. /**
  12. * Contains helper function that format numerical values in different ways.
  13. *
  14. * @api
  15. */
  16. class MetricsFormatter
  17. {
  18. /**
  19. * Returns a prettified string representation of a number. The result will have
  20. * thousands separators and a decimal point specific to the current locale, eg,
  21. * `'1,000,000.05'` or `'1.000.000,05'`.
  22. *
  23. * @param number $value
  24. * @return string
  25. */
  26. public static function getPrettyNumber($value)
  27. {
  28. static $decimalPoint = null;
  29. static $thousandsSeparator = null;
  30. if ($decimalPoint === null) {
  31. $locale = localeconv();
  32. $decimalPoint = $locale['decimal_point'];
  33. $thousandsSeparator = $locale['thousands_sep'];
  34. }
  35. return number_format($value, 0, $decimalPoint, $thousandsSeparator);
  36. }
  37. /**
  38. * Returns a prettified time value (in seconds).
  39. *
  40. * @param int $numberOfSeconds The number of seconds.
  41. * @param bool $displayTimeAsSentence If set to true, will output `"5min 17s"`, if false `"00:05:17"`.
  42. * @param bool $isHtml If true, replaces all spaces with `'&nbsp;'`.
  43. * @param bool $round Whether to round to the nearest second or not.
  44. * @return string
  45. */
  46. public static function getPrettyTimeFromSeconds($numberOfSeconds, $displayTimeAsSentence = true, $isHtml = true, $round = false)
  47. {
  48. $numberOfSeconds = $round ? (int)$numberOfSeconds : (float)$numberOfSeconds;
  49. $isNegative = false;
  50. if ($numberOfSeconds < 0) {
  51. $numberOfSeconds = -1 * $numberOfSeconds;
  52. $isNegative = true;
  53. }
  54. // Display 01:45:17 time format
  55. if ($displayTimeAsSentence === false) {
  56. $hours = floor($numberOfSeconds / 3600);
  57. $minutes = floor(($reminder = ($numberOfSeconds - $hours * 3600)) / 60);
  58. $seconds = floor($reminder - $minutes * 60);
  59. $time = sprintf("%02s", $hours) . ':' . sprintf("%02s", $minutes) . ':' . sprintf("%02s", $seconds);
  60. $centiSeconds = ($numberOfSeconds * 100) % 100;
  61. if ($centiSeconds) {
  62. $time .= '.' . sprintf("%02s", $centiSeconds);
  63. }
  64. if ($isNegative) {
  65. $time = '-' . $time;
  66. }
  67. return $time;
  68. }
  69. $secondsInYear = 86400 * 365.25;
  70. $years = floor($numberOfSeconds / $secondsInYear);
  71. $minusYears = $numberOfSeconds - $years * $secondsInYear;
  72. $days = floor($minusYears / 86400);
  73. $minusDays = $numberOfSeconds - $days * 86400;
  74. $hours = floor($minusDays / 3600);
  75. $minusDaysAndHours = $minusDays - $hours * 3600;
  76. $minutes = floor($minusDaysAndHours / 60);
  77. $seconds = $minusDaysAndHours - $minutes * 60;
  78. $precision = ($seconds > 0 && $seconds < 0.01 ? 3 : 2);
  79. $seconds = round($seconds, $precision);
  80. if ($years > 0) {
  81. $return = sprintf(Piwik::translate('General_YearsDays'), $years, $days);
  82. } elseif ($days > 0) {
  83. $return = sprintf(Piwik::translate('General_DaysHours'), $days, $hours);
  84. } elseif ($hours > 0) {
  85. $return = sprintf(Piwik::translate('General_HoursMinutes'), $hours, $minutes);
  86. } elseif ($minutes > 0) {
  87. $return = sprintf(Piwik::translate('General_MinutesSeconds'), $minutes, $seconds);
  88. } else {
  89. $return = sprintf(Piwik::translate('General_Seconds'), $seconds);
  90. }
  91. if ($isNegative) {
  92. $return = '-' . $return;
  93. }
  94. if ($isHtml) {
  95. return str_replace(' ', '&nbsp;', $return);
  96. }
  97. return $return;
  98. }
  99. /**
  100. * Returns a prettified memory size value.
  101. *
  102. * @param number $size The size in bytes.
  103. * @param string $unit The specific unit to use, if any. If null, the unit is determined by $size.
  104. * @param int $precision The precision to use when rounding.
  105. * @return string eg, `'128 M'` or `'256 K'`.
  106. */
  107. public static function getPrettySizeFromBytes($size, $unit = null, $precision = 1)
  108. {
  109. if ($size == 0) {
  110. return '0 M';
  111. }
  112. $units = array('B', 'K', 'M', 'G', 'T');
  113. foreach ($units as $currentUnit) {
  114. if ($size >= 1024 && $unit != $currentUnit) {
  115. $size = $size / 1024;
  116. } else {
  117. break;
  118. }
  119. }
  120. return round($size, $precision) . " " . $currentUnit;
  121. }
  122. /**
  123. * Returns a pretty formated monetary value using the currency associated with a site.
  124. *
  125. * @param int|string $value The monetary value to format.
  126. * @param int $idSite The ID of the site whose currency will be used.
  127. * @param bool $isHtml If true, replaces all spaces with `'&nbsp;'`.
  128. * @return string
  129. */
  130. public static function getPrettyMoney($value, $idSite, $isHtml = true)
  131. {
  132. $currencyBefore = MetricsFormatter::getCurrencySymbol($idSite);
  133. $space = ' ';
  134. if ($isHtml) {
  135. $space = '&nbsp;';
  136. }
  137. $currencyAfter = '';
  138. // (maybe more currencies prefer this notation?)
  139. $currencySymbolToAppend = array('€', 'kr', 'zł');
  140. // manually put the currency symbol after the amount
  141. if (in_array($currencyBefore, $currencySymbolToAppend)) {
  142. $currencyAfter = $space . $currencyBefore;
  143. $currencyBefore = '';
  144. }
  145. // if the input is a number (it could be a string or INPUT form),
  146. // and if this number is not an int, we round to precision 2
  147. if (is_numeric($value)) {
  148. if ($value == round($value)) {
  149. // 0.0 => 0
  150. $value = round($value);
  151. } else {
  152. $precision = GoalManager::REVENUE_PRECISION;
  153. $value = sprintf("%01." . $precision . "f", $value);
  154. }
  155. }
  156. $prettyMoney = $currencyBefore . $space . $value . $currencyAfter;
  157. return $prettyMoney;
  158. }
  159. /**
  160. * Prettifies a metric value based on the column name.
  161. *
  162. * @param int $idSite The ID of the site the metric is for (used if the column value is an amount of money).
  163. * @param string $columnName The metric name.
  164. * @param mixed $value The metric value.
  165. * @param bool $isHtml If true, replaces all spaces with `'&nbsp;'`.
  166. * @return string
  167. */
  168. public static function getPrettyValue($idSite, $columnName, $value, $isHtml)
  169. {
  170. // Display time in human readable
  171. if (strpos($columnName, 'time') !== false) {
  172. // Little hack: Display 15s rather than 00:00:15, only for "(avg|min|max)_generation_time"
  173. $timeAsSentence = (substr($columnName, -16) == '_time_generation');
  174. return self::getPrettyTimeFromSeconds($value, $timeAsSentence);
  175. }
  176. // Add revenue symbol to revenues
  177. if (strpos($columnName, 'revenue') !== false && strpos($columnName, 'evolution') === false) {
  178. return self::getPrettyMoney($value, $idSite, $isHtml);
  179. }
  180. // Add % symbol to rates
  181. if (strpos($columnName, '_rate') !== false) {
  182. if (strpos($value, "%") === false) {
  183. return $value . "%";
  184. }
  185. }
  186. return $value;
  187. }
  188. /**
  189. * Returns the currency symbol for a site.
  190. *
  191. * @param int $idSite The ID of the site to return the currency symbol for.
  192. * @return string eg, `'$'`.
  193. */
  194. public static function getCurrencySymbol($idSite)
  195. {
  196. $symbols = MetricsFormatter::getCurrencyList();
  197. $site = new Site($idSite);
  198. $currency = $site->getCurrency();
  199. if (isset($symbols[$currency])) {
  200. return $symbols[$currency][0];
  201. }
  202. return '';
  203. }
  204. /**
  205. * Returns the list of all known currency symbols.
  206. *
  207. * @return array An array mapping currency codes to their respective currency symbols
  208. * and a description, eg, `array('USD' => array('$', 'US dollar'))`.
  209. */
  210. public static function getCurrencyList()
  211. {
  212. static $currenciesList = null;
  213. if (is_null($currenciesList)) {
  214. require_once PIWIK_INCLUDE_PATH . '/core/DataFiles/Currencies.php';
  215. $currenciesList = $GLOBALS['Piwik_CurrencyList'];
  216. }
  217. return $currenciesList;
  218. }
  219. }