Zip.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. /**
  7. * Various methods for parsing Zip codes
  8. *
  9. */
  10. namespace Magento\Framework\Parse;
  11. class Zip
  12. {
  13. /**
  14. * Retrieve array of regions characterized by provided params
  15. *
  16. * @param string $state
  17. * @param string $zip
  18. * @return string[]
  19. */
  20. public static function parseRegions($state, $zip)
  21. {
  22. return !empty($zip) && $zip != '*' ? self::parseZip($zip) : ($state ? [$state] : ['*']);
  23. }
  24. /**
  25. * Retrieve array of regions characterized by provided zip code
  26. *
  27. * @param string $zip
  28. * @return string[]
  29. */
  30. public static function parseZip($zip)
  31. {
  32. if (strpos($zip, '-') === false) {
  33. return [$zip];
  34. } else {
  35. return self::zipRangeToZipPattern($zip);
  36. }
  37. }
  38. /**
  39. * Convert a Magento zip range to an array of zip patterns
  40. * (e.g., 12000-13999 -> [12*, 13*])
  41. *
  42. * @param string $zipRange
  43. * @return array
  44. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  45. * @SuppressWarnings(PHPMD.NPathComplexity)
  46. * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  47. */
  48. public static function zipRangeToZipPattern($zipRange)
  49. {
  50. $zipLength = 5;
  51. $zipPattern = [];
  52. if (!preg_match("/^(.+)-(.+)$/", $zipRange, $zipParts)) {
  53. return [$zipRange];
  54. }
  55. if ($zipParts[1] == $zipParts[2]) {
  56. return [$zipParts[1]];
  57. }
  58. if ($zipParts[1] > $zipParts[2]) {
  59. list($zipParts[2], $zipParts[1]) = [$zipParts[1], $zipParts[2]];
  60. }
  61. $from = str_split($zipParts[1]);
  62. $to = str_split($zipParts[2]);
  63. $startZip = '';
  64. $diffPosition = null;
  65. for ($pos = 0; $pos < $zipLength; $pos++) {
  66. if ($from[$pos] == $to[$pos]) {
  67. $startZip .= $from[$pos];
  68. } else {
  69. $diffPosition = $pos;
  70. break;
  71. }
  72. }
  73. /*
  74. * calculate zip-patterns
  75. */
  76. if (min(array_slice($to, $diffPosition)) == 9 && max(array_slice($from, $diffPosition)) == 0) {
  77. // particular case like 11000-11999 -> 11*
  78. return [$startZip . '*'];
  79. } else {
  80. // calculate approximate zip-patterns
  81. $start = $from[$diffPosition];
  82. $finish = $to[$diffPosition];
  83. if ($diffPosition < $zipLength - 1) {
  84. $start++;
  85. $finish--;
  86. }
  87. $end = $diffPosition < $zipLength - 1 ? '*' : '';
  88. for ($digit = $start; $digit <= $finish; $digit++) {
  89. $zipPattern[] = $startZip . $digit . $end;
  90. }
  91. }
  92. if ($diffPosition == $zipLength - 1) {
  93. return $zipPattern;
  94. }
  95. $nextAsteriskFrom = true;
  96. $nextAsteriskTo = true;
  97. for ($pos = $zipLength - 1; $pos > $diffPosition; $pos--) {
  98. // calculate zip-patterns based on $from value
  99. if ($from[$pos] == 0 && $nextAsteriskFrom) {
  100. $nextAsteriskFrom = true;
  101. } else {
  102. $subZip = '';
  103. for ($k = $diffPosition; $k < $pos; $k++) {
  104. $subZip .= $from[$k];
  105. }
  106. $delta = $nextAsteriskFrom ? 0 : 1;
  107. $end = $pos < $zipLength - 1 ? '*' : '';
  108. for ($i = $from[$pos] + $delta; $i <= 9; $i++) {
  109. $zipPattern[] = $startZip . $subZip . $i . $end;
  110. }
  111. $nextAsteriskFrom = false;
  112. }
  113. // calculate zip-patterns based on $to value
  114. if ($to[$pos] == 9 && $nextAsteriskTo) {
  115. $nextAsteriskTo = true;
  116. } else {
  117. $subZip = '';
  118. for ($k = $diffPosition; $k < $pos; $k++) {
  119. $subZip .= $to[$k];
  120. }
  121. $delta = $nextAsteriskTo ? 0 : 1;
  122. $end = $pos < $zipLength - 1 ? '*' : '';
  123. for ($i = 0; $i <= $to[$pos] - $delta; $i++) {
  124. $zipPattern[] = $startZip . $subZip . $i . $end;
  125. }
  126. $nextAsteriskTo = false;
  127. }
  128. }
  129. if ($nextAsteriskFrom) {
  130. $zipPattern[] = $startZip . $from[$diffPosition] . '*';
  131. }
  132. if ($nextAsteriskTo) {
  133. $zipPattern[] = $startZip . $to[$diffPosition] . '*';
  134. }
  135. return $zipPattern;
  136. }
  137. }