選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

171 行
4.7KB

  1. <?php
  2. /*
  3. * This file is part of the Fxp Composer Asset Plugin package.
  4. *
  5. * (c) François Pluchino <francois.pluchino@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Fxp\Composer\AssetPlugin\Converter;
  11. /**
  12. * Converter for Semver syntax version to composer syntax version.
  13. *
  14. * @author François Pluchino <francois.pluchino@gmail.com>
  15. */
  16. class SemverConverter implements VersionConverterInterface
  17. {
  18. /**
  19. * {@inheritdoc}
  20. */
  21. public function convertVersion($version)
  22. {
  23. if (in_array($version, array(null, '', 'latest'))) {
  24. return ('latest' === $version ? 'default || ' : '').'*';
  25. }
  26. $prefix = preg_match('/^[a-z]/', $version) ? substr($version, 0, 1) : '';
  27. $version = substr($version, strlen($prefix));
  28. $version = SemverUtil::convertVersionMetadata($version);
  29. return $prefix.$version;
  30. }
  31. /**
  32. * {@inheritdoc}
  33. */
  34. public function convertRange($range)
  35. {
  36. $range = $this->cleanRange(strtolower($range));
  37. return $this->matchRange($range);
  38. }
  39. /**
  40. * Clean the raw range.
  41. *
  42. * @param string $range
  43. *
  44. * @return string
  45. */
  46. protected function cleanRange($range)
  47. {
  48. foreach (array('<', '>', '=', '~', '^', '||') as $character) {
  49. $range = str_replace($character.' ', $character, $range);
  50. }
  51. $range = preg_replace('/(?:[vV])(\d+)/', '${1}', $range);
  52. return str_replace(' ||', '||', $range);
  53. }
  54. /**
  55. * Match the range.
  56. *
  57. * @param string $range The range cleaned
  58. *
  59. * @return string The range
  60. */
  61. protected function matchRange($range)
  62. {
  63. $pattern = '/(\ -\ )|(<)|(>)|(=)|(\|\|)|(\ )|(,)|(\~)|(\^)/';
  64. $matches = preg_split($pattern, $range, -1, PREG_SPLIT_DELIM_CAPTURE);
  65. $special = null;
  66. $replace = null;
  67. $first = true;
  68. foreach ($matches as $i => $match) {
  69. if ($first && '' !== $match) {
  70. $first = false;
  71. $match = '=' === $match ? 'EQUAL' : $match;
  72. }
  73. $this->matchRangeToken($i, $match, $matches, $special, $replace);
  74. }
  75. return implode('', $matches);
  76. }
  77. /**
  78. * Converts the token of the matched range.
  79. *
  80. * @param int $i
  81. * @param string $match
  82. * @param array $matches
  83. * @param string|null $special
  84. * @param string|null $replace
  85. */
  86. protected function matchRangeToken($i, $match, array &$matches, &$special, &$replace)
  87. {
  88. $matched = $this->matchRangeTokenStep1($i, $match, $matches, $special, $replace);
  89. if (!$matched) {
  90. $this->matchRangeTokenStep2($i, $match, $matches, $special, $replace);
  91. }
  92. }
  93. /**
  94. * Step1: Converts the token of the matched range.
  95. *
  96. * @param int $i
  97. * @param string $match
  98. * @param array $matches
  99. * @param string|null $special
  100. * @param string|null $replace
  101. *
  102. * @return bool
  103. */
  104. protected function matchRangeTokenStep1($i, $match, array &$matches, &$special, &$replace)
  105. {
  106. $matched = true;
  107. if (' - ' === $match) {
  108. $matches[$i - 1] = '>='.$matches[$i - 1];
  109. $matches[$i] = ',<=';
  110. } elseif (in_array($match, array('', '<', '>', '=', ','))) {
  111. $replace = in_array($match, array('<', '>')) ? $match : $replace;
  112. } elseif ('~' === $match) {
  113. $special = $match;
  114. } elseif (in_array($match, array('EQUAL', '^'))) {
  115. $special = $match;
  116. $matches[$i] = '';
  117. } else {
  118. $matched = false;
  119. }
  120. return $matched;
  121. }
  122. /**
  123. * Step2: Converts the token of the matched range.
  124. *
  125. * @param int $i
  126. * @param string $match
  127. * @param array $matches
  128. * @param string|null $special
  129. * @param string|null $replace
  130. */
  131. protected function matchRangeTokenStep2($i, $match, array &$matches, &$special, &$replace)
  132. {
  133. if (' ' === $match) {
  134. $matches[$i] = ',';
  135. } elseif ('||' === $match) {
  136. $matches[$i] = '|';
  137. } elseif (in_array($special, array('^'))) {
  138. $matches[$i] = SemverRangeUtil::replaceSpecialRange($this, $match);
  139. $special = null;
  140. } else {
  141. $match = '~' === $special ? str_replace(array('*', 'x', 'X'), '0', $match) : $match;
  142. $matches[$i] = $this->convertVersion($match);
  143. $matches[$i] = $replace
  144. ? SemverUtil::replaceAlias($matches[$i], $replace)
  145. : $matches[$i];
  146. $special = null;
  147. $replace = null;
  148. }
  149. }
  150. }