Pluralizer.php 3.6 KB

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