Format.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Locale;
  7. class Format implements \Magento\Framework\Locale\FormatInterface
  8. {
  9. /**
  10. * @var \Magento\Framework\App\ScopeResolverInterface
  11. */
  12. protected $_scopeResolver;
  13. /**
  14. * @var \Magento\Framework\Locale\ResolverInterface
  15. */
  16. protected $_localeResolver;
  17. /**
  18. * @var \Magento\Directory\Model\CurrencyFactory
  19. */
  20. protected $currencyFactory;
  21. /**
  22. * @param \Magento\Framework\App\ScopeResolverInterface $scopeResolver
  23. * @param ResolverInterface $localeResolver
  24. * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory
  25. */
  26. public function __construct(
  27. \Magento\Framework\App\ScopeResolverInterface $scopeResolver,
  28. \Magento\Framework\Locale\ResolverInterface $localeResolver,
  29. \Magento\Directory\Model\CurrencyFactory $currencyFactory
  30. ) {
  31. $this->_scopeResolver = $scopeResolver;
  32. $this->_localeResolver = $localeResolver;
  33. $this->currencyFactory = $currencyFactory;
  34. }
  35. /**
  36. * Returns the first found number from a string
  37. * Parsing depends on given locale (grouping and decimal)
  38. *
  39. * Examples for input:
  40. * ' 2345.4356,1234' = 23455456.1234
  41. * '+23,3452.123' = 233452.123
  42. * ' 12343 ' = 12343
  43. * '-9456km' = -9456
  44. * '0' = 0
  45. * '2 054,10' = 2054.1
  46. * '2'054.52' = 2054.52
  47. * '2,46 GB' = 2.46
  48. *
  49. * @param string|float|int $value
  50. * @return float|null
  51. */
  52. public function getNumber($value)
  53. {
  54. if ($value === null) {
  55. return null;
  56. }
  57. if (!is_string($value)) {
  58. return (float)$value;
  59. }
  60. //trim spaces and apostrophes
  61. $value = preg_replace('/[^0-9^\^.,-]/m', '', $value);
  62. $separatorComa = strpos($value, ',');
  63. $separatorDot = strpos($value, '.');
  64. if ($separatorComa !== false && $separatorDot !== false) {
  65. if ($separatorComa > $separatorDot) {
  66. $value = str_replace(['.', ','], ['', '.'], $value);
  67. } else {
  68. $value = str_replace(',', '', $value);
  69. }
  70. } elseif ($separatorComa !== false) {
  71. $value = str_replace(',', '.', $value);
  72. }
  73. return (float)$value;
  74. }
  75. /**
  76. * Returns an array with price formatting info
  77. *
  78. * @param string $localeCode Locale code.
  79. * @param string $currencyCode Currency code.
  80. * @return array
  81. */
  82. public function getPriceFormat($localeCode = null, $currencyCode = null)
  83. {
  84. $localeCode = $localeCode ?: $this->_localeResolver->getLocale();
  85. if ($currencyCode) {
  86. $currency = $this->currencyFactory->create()->load($currencyCode);
  87. } else {
  88. $currency = $this->_scopeResolver->getScope()->getCurrentCurrency();
  89. }
  90. $formatter = new \NumberFormatter(
  91. $localeCode . '@currency=' . $currency->getCode(),
  92. \NumberFormatter::CURRENCY
  93. );
  94. $format = $formatter->getPattern();
  95. $decimalSymbol = $formatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL);
  96. $groupSymbol = $formatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL);
  97. $pos = strpos($format, ';');
  98. if ($pos !== false) {
  99. $format = substr($format, 0, $pos);
  100. }
  101. $format = preg_replace("/[^0\#\.,]/", '', $format);
  102. $totalPrecision = 0;
  103. $decimalPoint = strpos($format, '.');
  104. if ($decimalPoint !== false) {
  105. $totalPrecision = strlen($format) - (strrpos($format, '.') + 1);
  106. } else {
  107. $decimalPoint = strlen($format);
  108. }
  109. $requiredPrecision = $totalPrecision;
  110. $t = substr($format, $decimalPoint);
  111. $pos = strpos($t, '#');
  112. if ($pos !== false) {
  113. $requiredPrecision = strlen($t) - $pos - $totalPrecision;
  114. }
  115. if (strrpos($format, ',') !== false) {
  116. $group = $decimalPoint - strrpos($format, ',') - 1;
  117. } else {
  118. $group = strrpos($format, '.');
  119. }
  120. $result = [
  121. //TODO: change interface
  122. 'pattern' => $currency->getOutputFormat(),
  123. 'precision' => $totalPrecision,
  124. 'requiredPrecision' => $requiredPrecision,
  125. 'decimalSymbol' => $decimalSymbol,
  126. 'groupSymbol' => $groupSymbol,
  127. 'groupLength' => $group,
  128. 'integerRequired' => $totalPrecision == 0,
  129. ];
  130. return $result;
  131. }
  132. }