/concrete/vendor/punic/punic/code/Unit.php

https://gitlab.com/koodersmiikka/operaatio-terveys · PHP · 244 lines · 180 code · 11 blank · 53 comment · 51 complexity · 3888f4ec8d05def7ed7a6e38e6c483ed MD5 · raw file

  1. <?php
  2. namespace Punic;
  3. /**
  4. * Units helper stuff.
  5. */
  6. class Unit
  7. {
  8. /**
  9. * Format a unit string.
  10. *
  11. * @param int|float|string $number The unit amount
  12. * @param string $unit The unit identifier (eg 'duration/millisecond' or 'millisecond')
  13. * @param string $width The format name; it can be 'long' (eg '3 milliseconds'), 'short' (eg '3 ms') or 'narrow' (eg '3ms'). You can also add a precision specifier ('long,2' or just '2')
  14. * @param string $locale The locale to use. If empty we'll use the default locale set in \Punic\Data
  15. *
  16. * @return string
  17. *
  18. * @throws Exception\ValueNotInList
  19. */
  20. public static function format($number, $unit, $width = 'short', $locale = '')
  21. {
  22. $data = Data::get('units', $locale);
  23. $precision = null;
  24. if (is_int($width)) {
  25. $precision = $width;
  26. $width = 'short';
  27. } elseif (is_string($width) && preg_match('/^(?:(.*),)?([+\\-]?\\d+)$/', $width, $m)) {
  28. $precision = intval($m[2]);
  29. $width = $m[1];
  30. if (!isset($width[0])) {
  31. $width = 'short';
  32. }
  33. }
  34. if ((strpos($width, '_') === 0) || (!isset($data[$width]))) {
  35. $widths = array();
  36. foreach (array_keys($data) as $w) {
  37. if (strpos($w, '_') !== 0) {
  38. $widths[] = $w;
  39. }
  40. }
  41. throw new Exception\ValueNotInList($width, $widths);
  42. }
  43. $data = $data[$width];
  44. if (strpos($unit, '/') === false) {
  45. $unitCategory = null;
  46. $unitID = null;
  47. foreach (array_keys($data) as $c) {
  48. if (strpos($c, '_') === false) {
  49. if (isset($data[$c][$unit])) {
  50. if ($unitCategory === null) {
  51. $unitCategory = $c;
  52. $unitID = $unit;
  53. } else {
  54. $unitCategory = null;
  55. break;
  56. }
  57. }
  58. }
  59. }
  60. } else {
  61. list($unitCategory, $unitID) = explode('/', $unit, 2);
  62. }
  63. $rules = null;
  64. if ((strpos($unit, '_') === false) && ($unitCategory !== null) && ($unitID !== null) && isset($data[$unitCategory]) && array_key_exists($unitID, $data[$unitCategory])) {
  65. $rules = $data[$unitCategory][$unitID];
  66. }
  67. if ($rules === null) {
  68. $units = array();
  69. foreach ($data as $c => $us) {
  70. if (strpos($c, '_') === false) {
  71. foreach (array_keys($us) as $u) {
  72. if (strpos($c, '_') === false) {
  73. $units[] = "$c/$u";
  74. }
  75. }
  76. }
  77. }
  78. throw new \Punic\Exception\ValueNotInList($unit, $units);
  79. }
  80. $pluralRule = Plural::getRule($number, $locale);
  81. //@codeCoverageIgnoreStart
  82. // These checks aren't necessary since $pluralRule should always be in $rules, but they don't hurt ;)
  83. if (!isset($rules[$pluralRule])) {
  84. if (isset($rules['other'])) {
  85. $pluralRule = 'other';
  86. } else {
  87. $availableRules = array_keys($rules);
  88. $pluralRule = $availableRules[0];
  89. }
  90. }
  91. //@codeCoverageIgnoreEnd
  92. return sprintf($rules[$pluralRule], Number::format($number, $precision, $locale));
  93. }
  94. /**
  95. * Retrieve the measurement systems and their localized names.
  96. *
  97. * @param string $locale The locale to use. If empty we'll use the default locale set in \Punic\Data
  98. *
  99. * @return array The array keys are the measurement system codes (eg 'metric', 'US', 'UK'), the values are the localized measurement system names (eg 'Metric', 'US', 'UK' for English)
  100. */
  101. public static function getMeasurementSystems($locale = '')
  102. {
  103. return Data::get('measurementSystemNames', $locale);
  104. }
  105. /**
  106. * Retrieve the measurement system for a specific territory.
  107. *
  108. * @param string $territoryCode The territory code (eg. 'US' for 'United States of America').
  109. *
  110. * @return string Return the measurement system code (eg: 'metric') for the specified territory. If $territoryCode is not valid we'll return an empty string.
  111. */
  112. public static function getMeasurementSystemFor($territoryCode)
  113. {
  114. $result = '';
  115. if (is_string($territoryCode) && preg_match('/^[a-z0-9]{2,3}$/i', $territoryCode)) {
  116. $territoryCode = strtoupper($territoryCode);
  117. $data = Data::getGeneric('measurementData');
  118. while (isset($territoryCode[0])) {
  119. if (isset($data['measurementSystem'][$territoryCode])) {
  120. $result = $data['measurementSystem'][$territoryCode];
  121. break;
  122. }
  123. $territoryCode = Territory::getParentTerritoryCode($territoryCode);
  124. }
  125. }
  126. return $result;
  127. }
  128. /**
  129. * Returns the list of countries that use a specific measurement system.
  130. *
  131. * @param string $measurementSystem The measurement system identifier ('metric', 'US' or 'UK')
  132. *
  133. * @return array The list of country IDs that use the specified measurement system (if $measurementSystem is invalid you'll get an empty array)
  134. */
  135. public static function getCountriesWithMeasurementSystem($measurementSystem)
  136. {
  137. $result = array();
  138. if (is_string($measurementSystem) && (isset($measurementSystem[0]))) {
  139. $someGroup = false;
  140. $data = Data::getGeneric('measurementData');
  141. foreach ($data['measurementSystem'] as $territory => $ms) {
  142. if (strcasecmp($measurementSystem, $ms) === 0) {
  143. $children = Territory::getChildTerritoryCodes($territory, true);
  144. if (empty($children)) {
  145. $result[] = $territory;
  146. } else {
  147. $someGroup = true;
  148. $result = array_merge($result, $children);
  149. }
  150. }
  151. }
  152. if ($someGroup) {
  153. $otherCountries = array();
  154. foreach ($data['measurementSystem'] as $territory => $ms) {
  155. if (($territory !== '001') && (strcasecmp($measurementSystem, $ms) !== 0)) {
  156. $children = Territory::getChildTerritoryCodes($territory, true);
  157. if (empty($children)) {
  158. $otherCountries[] = $territory;
  159. } else {
  160. $otherCountries = array_merge($otherCountries, $children);
  161. }
  162. }
  163. }
  164. $result = array_values(array_diff($result, $otherCountries));
  165. }
  166. }
  167. return $result;
  168. }
  169. /**
  170. * Retrieve the standard paper size for a specific territory.
  171. *
  172. * @param string $territoryCode The territory code (eg. 'US' for 'United States of America').
  173. *
  174. * @return string Return the standard paper size (eg: 'A4' or 'US-Letter') for the specified territory. If $territoryCode is not valid we'll return an empty string.
  175. */
  176. public static function getPaperSizeFor($territoryCode)
  177. {
  178. $result = '';
  179. if (is_string($territoryCode) && preg_match('/^[a-z0-9]{2,3}$/i', $territoryCode)) {
  180. $territoryCode = strtoupper($territoryCode);
  181. $data = Data::getGeneric('measurementData');
  182. while (isset($territoryCode[0])) {
  183. if (isset($data['paperSize'][$territoryCode])) {
  184. $result = $data['paperSize'][$territoryCode];
  185. break;
  186. }
  187. $territoryCode = Territory::getParentTerritoryCode($territoryCode);
  188. }
  189. }
  190. return $result;
  191. }
  192. /**
  193. * Returns the list of countries that use a specific paper size by default.
  194. *
  195. * @param string $paperSize The paper size identifier ('A4' or 'US-Letter')
  196. *
  197. * @return array The list of country IDs that use the specified paper size (if $paperSize is invalid you'll get an empty array)
  198. */
  199. public static function getCountriesWithPaperSize($paperSize)
  200. {
  201. $result = array();
  202. if (is_string($paperSize) && (isset($paperSize[0]))) {
  203. $someGroup = false;
  204. $data = Data::getGeneric('measurementData');
  205. foreach ($data['paperSize'] as $territory => $ms) {
  206. if (strcasecmp($paperSize, $ms) === 0) {
  207. $children = Territory::getChildTerritoryCodes($territory, true);
  208. if (empty($children)) {
  209. $result[] = $territory;
  210. } else {
  211. $someGroup = true;
  212. $result = array_merge($result, $children);
  213. }
  214. }
  215. }
  216. if ($someGroup) {
  217. $otherCountries = array();
  218. foreach ($data['paperSize'] as $territory => $ms) {
  219. if (($territory !== '001') && (strcasecmp($paperSize, $ms) !== 0)) {
  220. $children = Territory::getChildTerritoryCodes($territory, true);
  221. if (empty($children)) {
  222. $otherCountries[] = $territory;
  223. } else {
  224. $otherCountries = array_merge($otherCountries, $children);
  225. }
  226. }
  227. }
  228. $result = array_values(array_diff($result, $otherCountries));
  229. }
  230. }
  231. return $result;
  232. }
  233. }