Pluralizer.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace Hyperf\Utils;
  12. use Doctrine\Inflector\CachedWordInflector;
  13. use Doctrine\Inflector\Inflector;
  14. use Doctrine\Inflector\Rules\English;
  15. use Doctrine\Inflector\RulesetInflector;
  16. class Pluralizer
  17. {
  18. /**
  19. * Uncountable word forms.
  20. *
  21. * @var array
  22. */
  23. public static $uncountable
  24. = [
  25. 'audio',
  26. 'bison',
  27. 'cattle',
  28. 'chassis',
  29. 'compensation',
  30. 'coreopsis',
  31. 'data',
  32. 'deer',
  33. 'education',
  34. 'emoji',
  35. 'equipment',
  36. 'evidence',
  37. 'feedback',
  38. 'firmware',
  39. 'fish',
  40. 'furniture',
  41. 'gold',
  42. 'hardware',
  43. 'information',
  44. 'jedi',
  45. 'kin',
  46. 'knowledge',
  47. 'love',
  48. 'metadata',
  49. 'money',
  50. 'moose',
  51. 'news',
  52. 'nutrition',
  53. 'offspring',
  54. 'plankton',
  55. 'pokemon',
  56. 'police',
  57. 'rain',
  58. 'rice',
  59. 'series',
  60. 'sheep',
  61. 'software',
  62. 'species',
  63. 'swine',
  64. 'traffic',
  65. 'wheat',
  66. ];
  67. /**
  68. * @var null|Inflector
  69. */
  70. protected static $inflector;
  71. /**
  72. * Get the plural form of an English word.
  73. *
  74. * @param string $value
  75. * @param int $count
  76. * @return string
  77. */
  78. public static function plural($value, $count = 2)
  79. {
  80. if ((int) abs($count) === 1 || static::uncountable($value)) {
  81. return $value;
  82. }
  83. $plural = static::getInflector()->pluralize($value);
  84. return static::matchCase($plural, $value);
  85. }
  86. /**
  87. * Get the singular form of an English word.
  88. *
  89. * @param string $value
  90. * @return string
  91. */
  92. public static function singular($value)
  93. {
  94. $singular = static::getInflector()->singularize($value);
  95. return static::matchCase($singular, $value);
  96. }
  97. public static function setInflector(?Inflector $inflector): void
  98. {
  99. static::$inflector = $inflector;
  100. }
  101. /**
  102. * Get the inflector instance.
  103. */
  104. public static function getInflector(): Inflector
  105. {
  106. if (is_null(static::$inflector)) {
  107. static::$inflector = new Inflector(
  108. new CachedWordInflector(new RulesetInflector(
  109. English\Rules::getSingularRuleset()
  110. )),
  111. new CachedWordInflector(new RulesetInflector(
  112. English\Rules::getPluralRuleset()
  113. ))
  114. );
  115. }
  116. return static::$inflector;
  117. }
  118. /**
  119. * Determine if the given value is uncountable.
  120. *
  121. * @param string $value
  122. * @return bool
  123. */
  124. protected static function uncountable($value)
  125. {
  126. return in_array(strtolower($value), static::$uncountable);
  127. }
  128. /**
  129. * Attempt to match the case on two strings.
  130. *
  131. * @param string $value
  132. * @param string $comparison
  133. * @return string
  134. */
  135. protected static function matchCase($value, $comparison)
  136. {
  137. $functions = ['mb_strtolower', 'mb_strtoupper', 'ucfirst', 'ucwords'];
  138. foreach ($functions as $function) {
  139. if (call_user_func($function, $comparison) === $comparison) {
  140. return call_user_func($function, $value);
  141. }
  142. }
  143. return $value;
  144. }
  145. }