Rector 0.18.6

This commit is contained in:
Tomas Votruba 2023-10-24 15:00:59 +00:00
parent 52923dc606
commit 02041b2207
57 changed files with 2181 additions and 47 deletions

View File

@ -3,6 +3,7 @@
declare (strict_types=1);
namespace Rector\Naming\ExpectedNameResolver;
use RectorPrefix202310\Doctrine\Inflector\Inflector;
use RectorPrefix202310\Nette\Utils\Strings;
use Rector\Core\Util\StringUtils;
/**
@ -10,6 +11,11 @@ use Rector\Core\Util\StringUtils;
*/
final class InflectorSingularResolver
{
/**
* @readonly
* @var \Doctrine\Inflector\Inflector
*/
private $inflector;
/**
* @var array<string, string>
*/
@ -28,6 +34,10 @@ final class InflectorSingularResolver
* @var string
*/
private const CAMELCASE = 'camelcase';
public function __construct(Inflector $inflector)
{
$this->inflector = $inflector;
}
public function resolve(string $currentName) : string
{
$matchBy = Strings::match($currentName, self::BY_MIDDLE_REGEX);
@ -70,7 +80,7 @@ final class InflectorSingularResolver
$camelCases = Strings::matchAll($currentName, self::CAMELCASE_REGEX);
$resolvedName = '';
foreach ($camelCases as $camelCase) {
$value = $this->singularize($camelCase[self::CAMELCASE]);
$value = $this->inflector->singularize($camelCase[self::CAMELCASE]);
if (\in_array($camelCase[self::CAMELCASE], ['is', 'has'], \true)) {
$value = $camelCase[self::CAMELCASE];
}
@ -78,30 +88,4 @@ final class InflectorSingularResolver
}
return $resolvedName;
}
// see https://gist.github.com/peter-mcconnell/9757549
private function singularize(string $word) : string
{
$singular = ['/(quiz)zes$/i' => '\\1', '/(matr)ices$/i' => '\\1ix', '/(vert|ind)ices$/i' => '\\1ex', '/^(ox)en/i' => '\\1', '/^(axe)s$/i' => '\\1', '/(alias|status|iris|hoax|hero|gas|fax|circus|canvas|atlas)es$/i' => '\\1', '/([octop|vir])i$/i' => '\\1us', '/(cris|ax|test)es$/i' => '\\1is', '/(shoe|grave|glove|foe|dive|database|curve|cookie|cave|cache|avalanche|abuse)s$/i' => '\\1', '/(o)es$/i' => '\\1', '/(bus|lens)es$/i' => '\\1', '/([m|l])ice$/i' => '\\1ouse', '/(x|ch|ss|sh)es$/i' => '\\1', '/(m)ovies$/i' => '\\1ovie', '/(s)eries$/i' => '\\1eries', '/([^aeiouy]|qu)ies$/i' => '\\1y', '/([lr])ves$/i' => '\\1f', '/(tive)s$/i' => '\\1', '/(hive)s$/i' => '\\1', '/([^f])ves$/i' => '\\1fe', '/(^analy)ses$/i' => '\\1sis', '/((a)naly|(b)a|(d)iagno|empha|(p)arenthe|(p)rogno|(s)ynop|(t)he|(oa)|neuro)ses$/i' => '1\\2sis', '/([ti]|memorand|curricul)a$/i' => '\\1um', '/(n)ews$/i' => '\\1ews', '/s$/i' => ''];
$irregular = ['alumnus' => 'alumni', 'person' => 'people', 'man' => 'men', 'bacillus' => 'bacilli', 'criterion' => 'criteria', 'fungus' => 'fungi', 'foot' => 'feet', 'goose' => 'geese', 'genus' => 'genera', 'hippopotamus' => 'hippopotami', 'child' => 'children', 'code' => 'codes', 'octopus' => 'octopuses', 'olive' => 'olives', 'chateau' => 'chateaux', 'plateau' => 'plateaux', 'niveau' => 'niveaux', 'passerby' => 'passersby', 'save' => 'saves', 'sex' => 'sexes', 'syllabus' => 'syllabi', 'stimulus' => 'stimuli', 'sku' => 'skus', 'sieve' => 'sieves', 'taxon' => 'taxa', 'taxi' => 'taxis', 'tax' => 'taxes', 'tooth' => 'teeth', 'tights' => 'tights', 'Thief' => 'Thieves', 'terminus' => 'termini', 'larva' => 'larvae', 'leaf' => 'leaves', 'loaf' => 'loaves', 'move' => 'moves', 'nucleus' => 'nuclei', 'valve' => 'valves', 'wave' => 'waves', 'zombie' => 'zombies'];
// keep words ending in $ignore
$ignore = ['breeches', 'britches', 'cantus', 'chassis', 'corps', 'coreopsis', 'contretemps', 'coitus', 'clothes', 'clippers', 'data', 'diabetes', 'debris', 'equipment', 'gallows', 'hijinks', 'herpes', 'headquarters', 'information', 'rice', 'socialmedia', 'jeans', 'jackanapes', 'nodemedia', 'money', 'mumps', 'mews', 'innings', 'nexus', 'rhinoceros', 'rabies', 'pants', 'police', 'pliers', 'progress', 'proceedings', 'pincers', 'scissors', 'species', 'series', 'status', 'shorts', 'shears', 'fish', 'sheep', 'press', 'sms', 'trousers', 'trivia', 'yengeese'];
$lower_word = \strtolower($word);
foreach ($ignore as $ignore_word) {
if (\substr($lower_word, -1 * \strlen($ignore_word)) === $ignore_word) {
return $word;
}
}
foreach ($irregular as $singular_word => $plural_word) {
$arr = Strings::match($word, '/(' . $plural_word . ')$/i');
if ($arr !== null) {
return Strings::replace($word, '/(' . $plural_word . ')$/i', \substr($arr[0], 0, 1) . \substr($singular_word, 1));
}
}
foreach ($singular as $rule => $replacement) {
if (Strings::match($word, $rule) !== null) {
return Strings::replace($word, $rule, $replacement);
}
}
return $word;
}
}

View File

@ -13,7 +13,7 @@ use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypeWithClassName;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Util\StringUtils;
use Rector\Naming\ExpectedNameResolver\InflectorSingularResolver;
use Rector\Naming\RectorNamingInflector;
use Rector\Naming\ValueObject\ExpectedName;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
@ -25,9 +25,9 @@ final class PropertyNaming
{
/**
* @readonly
* @var \Rector\Naming\ExpectedNameResolver\InflectorSingularResolver
* @var \Rector\Naming\RectorNamingInflector
*/
private $inflectorSingularResolver;
private $rectorNamingInflector;
/**
* @readonly
* @var \Rector\NodeTypeResolver\NodeTypeResolver
@ -55,9 +55,9 @@ final class PropertyNaming
* @var string
*/
private const GET_PREFIX_REGEX = '#^get(?<root_name>[A-Z].+)#';
public function __construct(InflectorSingularResolver $inflectorSingularResolver, NodeTypeResolver $nodeTypeResolver)
public function __construct(RectorNamingInflector $rectorNamingInflector, NodeTypeResolver $nodeTypeResolver)
{
$this->inflectorSingularResolver = $inflectorSingularResolver;
$this->rectorNamingInflector = $rectorNamingInflector;
$this->nodeTypeResolver = $nodeTypeResolver;
}
public function getExpectedNameFromMethodName(string $methodName) : ?ExpectedName
@ -67,7 +67,7 @@ final class PropertyNaming
return null;
}
$originalName = \lcfirst((string) $matches['root_name']);
return new ExpectedName($originalName, $this->inflectorSingularResolver->resolve($originalName));
return new ExpectedName($originalName, $this->rectorNamingInflector->singularize($originalName));
}
public function getExpectedNameFromType(Type $type) : ?ExpectedName
{
@ -99,7 +99,7 @@ final class PropertyNaming
$shortClassName = $this->normalizeShortClassName($shortClassName);
// prolong too short generic names with one namespace up
$originalName = $this->prolongIfTooShort($shortClassName, $className);
return new ExpectedName($originalName, $this->inflectorSingularResolver->resolve($originalName));
return new ExpectedName($originalName, $this->rectorNamingInflector->singularize($originalName));
}
/**
* @param \PHPStan\Type\ThisType|\PHPStan\Type\ObjectType|string $objectType

View File

@ -0,0 +1,34 @@
<?php
declare (strict_types=1);
namespace Rector\Naming;
use RectorPrefix202310\Doctrine\Inflector\Inflector;
use RectorPrefix202310\Nette\Utils\Strings;
final class RectorNamingInflector
{
/**
* @readonly
* @var \Doctrine\Inflector\Inflector
*/
private $inflector;
/**
* @var string
* @see https://regex101.com/r/VqVvke/3
*/
private const DATA_INFO_SUFFIX_REGEX = '#^(?<prefix>.+)(?<suffix>Data|Info)$#';
public function __construct(Inflector $inflector)
{
$this->inflector = $inflector;
}
public function singularize(string $name) : string
{
$matches = Strings::match($name, self::DATA_INFO_SUFFIX_REGEX);
if ($matches === null) {
return $this->inflector->singularize($name);
}
$singularized = $this->inflector->singularize($matches['prefix']);
$uninflectable = $matches['suffix'];
return $singularized . $uninflectable;
}
}

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '1c54292ed68e46f4ddfa2adb21f28130f308b99c';
public const PACKAGE_VERSION = '0.18.6';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-10-24 16:57:53';
public const RELEASE_DATE = '2023-10-24 16:57:04';
/**
* @var int
*/

View File

@ -3,6 +3,8 @@
declare (strict_types=1);
namespace Rector\Core\DependencyInjection;
use RectorPrefix202310\Doctrine\Inflector\Inflector;
use RectorPrefix202310\Doctrine\Inflector\Rules\English\InflectorFactory;
use RectorPrefix202310\Illuminate\Container\Container;
use PhpParser\Lexer;
use PHPStan\Analyser\NodeScopeResolver;
@ -258,6 +260,10 @@ final class LazyContainerFactory
return $application;
});
$rectorConfig->when(ConsoleApplication::class)->needs('$commands')->giveTagged(Command::class);
$rectorConfig->singleton(Inflector::class, static function () : Inflector {
$inflectorFactory = new InflectorFactory();
return $inflectorFactory->build();
});
$rectorConfig->tag(ProcessCommand::class, Command::class);
$rectorConfig->tag(WorkerCommand::class, Command::class);
$rectorConfig->tag(SetupCICommand::class, Command::class);

2
vendor/autoload.php vendored
View File

@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitb5644708b7ed04b3c875c18370cf2e53::getLoader();
return ComposerAutoloaderInit18ad0e678efbbb500e116f7c54cccdd4::getLoader();

View File

@ -367,6 +367,47 @@ return array(
'RectorPrefix202310\\Composer\\XdebugHandler\\Process' => $vendorDir . '/composer/xdebug-handler/src/Process.php',
'RectorPrefix202310\\Composer\\XdebugHandler\\Status' => $vendorDir . '/composer/xdebug-handler/src/Status.php',
'RectorPrefix202310\\Composer\\XdebugHandler\\XdebugHandler' => $vendorDir . '/composer/xdebug-handler/src/XdebugHandler.php',
'RectorPrefix202310\\Doctrine\\Inflector\\CachedWordInflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/CachedWordInflector.php',
'RectorPrefix202310\\Doctrine\\Inflector\\GenericLanguageInflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Inflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Inflector.php',
'RectorPrefix202310\\Doctrine\\Inflector\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Language' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Language.php',
'RectorPrefix202310\\Doctrine\\Inflector\\LanguageInflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/LanguageInflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\NoopWordInflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/NoopWordInflector.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\English\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\English\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\English\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\English\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\French\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\French\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\French\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\French\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\NorwegianBokmal\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Pattern' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Pattern.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Patterns' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Patterns.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Portuguese\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Portuguese\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Portuguese\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Portuguese\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Ruleset' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Ruleset.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Spanish\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Spanish\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Spanish\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Spanish\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Substitution' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitution.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Substitutions' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitutions.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Transformation' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformation.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Transformations' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformations.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Turkish\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Turkish\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Turkish\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Turkish\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Word' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Word.php',
'RectorPrefix202310\\Doctrine\\Inflector\\RulesetInflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/RulesetInflector.php',
'RectorPrefix202310\\Doctrine\\Inflector\\WordInflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/WordInflector.php',
'RectorPrefix202310\\Evenement\\EventEmitter' => $vendorDir . '/evenement/evenement/src/EventEmitter.php',
'RectorPrefix202310\\Evenement\\EventEmitterInterface' => $vendorDir . '/evenement/evenement/src/EventEmitterInterface.php',
'RectorPrefix202310\\Evenement\\EventEmitterTrait' => $vendorDir . '/evenement/evenement/src/EventEmitterTrait.php',
@ -1492,6 +1533,7 @@ return array(
'Rector\\Naming\\PropertyRenamer\\MatchTypePropertyRenamer' => $baseDir . '/rules/Naming/PropertyRenamer/MatchTypePropertyRenamer.php',
'Rector\\Naming\\PropertyRenamer\\PropertyFetchRenamer' => $baseDir . '/rules/Naming/PropertyRenamer/PropertyFetchRenamer.php',
'Rector\\Naming\\PropertyRenamer\\PropertyPromotionRenamer' => $baseDir . '/rules/Naming/PropertyRenamer/PropertyPromotionRenamer.php',
'Rector\\Naming\\RectorNamingInflector' => $baseDir . '/rules/Naming/RectorNamingInflector.php',
'Rector\\Naming\\Rector\\Assign\\RenameVariableToMatchMethodCallReturnTypeRector' => $baseDir . '/rules/Naming/Rector/Assign/RenameVariableToMatchMethodCallReturnTypeRector.php',
'Rector\\Naming\\Rector\\ClassMethod\\RenameParamToMatchTypeRector' => $baseDir . '/rules/Naming/Rector/ClassMethod/RenameParamToMatchTypeRector.php',
'Rector\\Naming\\Rector\\ClassMethod\\RenameVariableToMatchNewTypeRector' => $baseDir . '/rules/Naming/Rector/ClassMethod/RenameVariableToMatchNewTypeRector.php',

View File

@ -37,6 +37,7 @@ return array(
'RectorPrefix202310\\Illuminate\\Container\\' => array($vendorDir . '/illuminate/container'),
'RectorPrefix202310\\Fidry\\CpuCoreCounter\\' => array($vendorDir . '/fidry/cpu-core-counter/src'),
'RectorPrefix202310\\Evenement\\' => array($vendorDir . '/evenement/evenement/src'),
'RectorPrefix202310\\Doctrine\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector'),
'RectorPrefix202310\\Composer\\XdebugHandler\\' => array($vendorDir . '/composer/xdebug-handler/src'),
'RectorPrefix202310\\Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'),
'RectorPrefix202310\\Composer\\Pcre\\' => array($vendorDir . '/composer/pcre/src'),

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitb5644708b7ed04b3c875c18370cf2e53
class ComposerAutoloaderInit18ad0e678efbbb500e116f7c54cccdd4
{
private static $loader;
@ -22,17 +22,17 @@ class ComposerAutoloaderInitb5644708b7ed04b3c875c18370cf2e53
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitb5644708b7ed04b3c875c18370cf2e53', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit18ad0e678efbbb500e116f7c54cccdd4', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitb5644708b7ed04b3c875c18370cf2e53', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit18ad0e678efbbb500e116f7c54cccdd4', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit18ad0e678efbbb500e116f7c54cccdd4::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInit18ad0e678efbbb500e116f7c54cccdd4::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53
class ComposerStaticInit18ad0e678efbbb500e116f7c54cccdd4
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -49,6 +49,7 @@ class ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53
'RectorPrefix202310\\Illuminate\\Container\\' => 40,
'RectorPrefix202310\\Fidry\\CpuCoreCounter\\' => 40,
'RectorPrefix202310\\Evenement\\' => 29,
'RectorPrefix202310\\Doctrine\\Inflector\\' => 38,
'RectorPrefix202310\\Composer\\XdebugHandler\\' => 42,
'RectorPrefix202310\\Composer\\Semver\\' => 35,
'RectorPrefix202310\\Composer\\Pcre\\' => 33,
@ -192,6 +193,10 @@ class ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53
array (
0 => __DIR__ . '/..' . '/evenement/evenement/src',
),
'RectorPrefix202310\\Doctrine\\Inflector\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector',
),
'RectorPrefix202310\\Composer\\XdebugHandler\\' =>
array (
0 => __DIR__ . '/..' . '/composer/xdebug-handler/src',
@ -580,6 +585,47 @@ class ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53
'RectorPrefix202310\\Composer\\XdebugHandler\\Process' => __DIR__ . '/..' . '/composer/xdebug-handler/src/Process.php',
'RectorPrefix202310\\Composer\\XdebugHandler\\Status' => __DIR__ . '/..' . '/composer/xdebug-handler/src/Status.php',
'RectorPrefix202310\\Composer\\XdebugHandler\\XdebugHandler' => __DIR__ . '/..' . '/composer/xdebug-handler/src/XdebugHandler.php',
'RectorPrefix202310\\Doctrine\\Inflector\\CachedWordInflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/CachedWordInflector.php',
'RectorPrefix202310\\Doctrine\\Inflector\\GenericLanguageInflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Inflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Inflector.php',
'RectorPrefix202310\\Doctrine\\Inflector\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Language' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Language.php',
'RectorPrefix202310\\Doctrine\\Inflector\\LanguageInflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/LanguageInflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\NoopWordInflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/NoopWordInflector.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\English\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\English\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\English\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\English\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\French\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\French\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\French\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\French\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\NorwegianBokmal\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Pattern' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Pattern.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Patterns' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Patterns.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Portuguese\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Portuguese\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Portuguese\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Portuguese\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Ruleset' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Ruleset.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Spanish\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Spanish\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Spanish\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Spanish\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Substitution' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitution.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Substitutions' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitutions.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Transformation' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformation.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Transformations' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformations.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Turkish\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Inflectible.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Turkish\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/InflectorFactory.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Turkish\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Rules.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Turkish\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Uninflected.php',
'RectorPrefix202310\\Doctrine\\Inflector\\Rules\\Word' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Word.php',
'RectorPrefix202310\\Doctrine\\Inflector\\RulesetInflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/RulesetInflector.php',
'RectorPrefix202310\\Doctrine\\Inflector\\WordInflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/WordInflector.php',
'RectorPrefix202310\\Evenement\\EventEmitter' => __DIR__ . '/..' . '/evenement/evenement/src/EventEmitter.php',
'RectorPrefix202310\\Evenement\\EventEmitterInterface' => __DIR__ . '/..' . '/evenement/evenement/src/EventEmitterInterface.php',
'RectorPrefix202310\\Evenement\\EventEmitterTrait' => __DIR__ . '/..' . '/evenement/evenement/src/EventEmitterTrait.php',
@ -1705,6 +1751,7 @@ class ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53
'Rector\\Naming\\PropertyRenamer\\MatchTypePropertyRenamer' => __DIR__ . '/../..' . '/rules/Naming/PropertyRenamer/MatchTypePropertyRenamer.php',
'Rector\\Naming\\PropertyRenamer\\PropertyFetchRenamer' => __DIR__ . '/../..' . '/rules/Naming/PropertyRenamer/PropertyFetchRenamer.php',
'Rector\\Naming\\PropertyRenamer\\PropertyPromotionRenamer' => __DIR__ . '/../..' . '/rules/Naming/PropertyRenamer/PropertyPromotionRenamer.php',
'Rector\\Naming\\RectorNamingInflector' => __DIR__ . '/../..' . '/rules/Naming/RectorNamingInflector.php',
'Rector\\Naming\\Rector\\Assign\\RenameVariableToMatchMethodCallReturnTypeRector' => __DIR__ . '/../..' . '/rules/Naming/Rector/Assign/RenameVariableToMatchMethodCallReturnTypeRector.php',
'Rector\\Naming\\Rector\\ClassMethod\\RenameParamToMatchTypeRector' => __DIR__ . '/../..' . '/rules/Naming/Rector/ClassMethod/RenameParamToMatchTypeRector.php',
'Rector\\Naming\\Rector\\ClassMethod\\RenameVariableToMatchNewTypeRector' => __DIR__ . '/../..' . '/rules/Naming/Rector/ClassMethod/RenameVariableToMatchNewTypeRector.php',
@ -2552,9 +2599,9 @@ class ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitb5644708b7ed04b3c875c18370cf2e53::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit18ad0e678efbbb500e116f7c54cccdd4::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit18ad0e678efbbb500e116f7c54cccdd4::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit18ad0e678efbbb500e116f7c54cccdd4::$classMap;
}, null, ClassLoader::class);
}

View File

@ -294,6 +294,100 @@
],
"install-path": ".\/xdebug-handler"
},
{
"name": "doctrine\/inflector",
"version": "2.0.8",
"version_normalized": "2.0.8.0",
"source": {
"type": "git",
"url": "https:\/\/github.com\/doctrine\/inflector.git",
"reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/doctrine\/inflector\/zipball\/f9301a5b2fb1216b2b08f02ba04dc45423db6bff",
"reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"doctrine\/coding-standard": "^11.0",
"phpstan\/phpstan": "^1.8",
"phpstan\/phpstan-phpunit": "^1.1",
"phpstan\/phpstan-strict-rules": "^1.3",
"phpunit\/phpunit": "^8.5 || ^9.5",
"vimeo\/psalm": "^4.25 || ^5.4"
},
"time": "2023-06-16T13:40:37+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"RectorPrefix202310\\Doctrine\\Inflector\\": "lib\/Doctrine\/Inflector"
}
},
"notification-url": "https:\/\/packagist.org\/downloads\/",
"license": [
"MIT"
],
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper\/lowercase and singular\/plural forms of words.",
"homepage": "https:\/\/www.doctrine-project.org\/projects\/inflector.html",
"keywords": [
"inflection",
"inflector",
"lowercase",
"manipulation",
"php",
"plural",
"singular",
"strings",
"uppercase",
"words"
],
"support": {
"issues": "https:\/\/github.com\/doctrine\/inflector\/issues",
"source": "https:\/\/github.com\/doctrine\/inflector\/tree\/2.0.8"
},
"funding": [
{
"url": "https:\/\/www.doctrine-project.org\/sponsorship.html",
"type": "custom"
},
{
"url": "https:\/\/www.patreon.com\/phpdoctrine",
"type": "patreon"
},
{
"url": "https:\/\/tidelift.com\/funding\/github\/packagist\/doctrine%2Finflector",
"type": "tidelift"
}
],
"install-path": "..\/doctrine\/inflector"
},
{
"name": "evenement\/evenement",
"version": "v3.0.2",

File diff suppressed because one or more lines are too long

19
vendor/doctrine/inflector/LICENSE vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2006-2015 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

7
vendor/doctrine/inflector/README.md vendored Normal file
View File

@ -0,0 +1,7 @@
# Doctrine Inflector
Doctrine Inflector is a small library that can perform string manipulations
with regard to uppercase/lowercase and singular/plural forms of words.
[![Build Status](https://github.com/doctrine/inflector/workflows/Continuous%20Integration/badge.svg)](https://github.com/doctrine/inflector/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A4.0.x)
[![Code Coverage](https://codecov.io/gh/doctrine/inflector/branch/2.0.x/graph/badge.svg)](https://codecov.io/gh/doctrine/inflector/branch/2.0.x)

67
vendor/doctrine/inflector/composer.json vendored Normal file
View File

@ -0,0 +1,67 @@
{
"name": "doctrine\/inflector",
"type": "library",
"description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper\/lowercase and singular\/plural forms of words.",
"keywords": [
"php",
"strings",
"words",
"manipulation",
"inflector",
"inflection",
"uppercase",
"lowercase",
"singular",
"plural"
],
"homepage": "https:\/\/www.doctrine-project.org\/projects\/inflector.html",
"license": "MIT",
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"doctrine\/coding-standard": "^11.0",
"phpstan\/phpstan": "^1.8",
"phpstan\/phpstan-phpunit": "^1.1",
"phpstan\/phpstan-strict-rules": "^1.3",
"phpunit\/phpunit": "^8.5 || ^9.5",
"vimeo\/psalm": "^4.25 || ^5.4"
},
"autoload": {
"psr-4": {
"RectorPrefix202310\\Doctrine\\Inflector\\": "lib\/Doctrine\/Inflector"
}
},
"autoload-dev": {
"psr-4": {
"RectorPrefix202310\\Doctrine\\Tests\\Inflector\\": "tests\/Doctrine\/Tests\/Inflector"
}
},
"config": {
"allow-plugins": {
"dealerdirect\/phpcodesniffer-composer-installer": true
}
}
}

View File

@ -0,0 +1,226 @@
Introduction
============
The Doctrine Inflector has methods for inflecting text. The features include pluralization,
singularization, converting between camelCase and under_score and capitalizing
words.
Installation
============
You can install the Inflector with composer:
.. code-block:: console
$ composer require doctrine/inflector
Usage
=====
Using the inflector is easy, you can create a new ``Doctrine\Inflector\Inflector`` instance by using
the ``Doctrine\Inflector\InflectorFactory`` class:
.. code-block:: php
use Doctrine\Inflector\InflectorFactory;
$inflector = InflectorFactory::create()->build();
By default it will create an English inflector. If you want to use another language, just pass the language
you want to create an inflector for to the ``createForLanguage()`` method:
.. code-block:: php
use Doctrine\Inflector\InflectorFactory;
use Doctrine\Inflector\Language;
$inflector = InflectorFactory::createForLanguage(Language::SPANISH)->build();
The supported languages are as follows:
- ``Language::ENGLISH``
- ``Language::FRENCH``
- ``Language::NORWEGIAN_BOKMAL``
- ``Language::PORTUGUESE``
- ``Language::SPANISH``
- ``Language::TURKISH``
If you want to manually construct the inflector instead of using a factory, you can do so like this:
.. code-block:: php
use Doctrine\Inflector\CachedWordInflector;
use Doctrine\Inflector\RulesetInflector;
use Doctrine\Inflector\Rules\English;
$inflector = new Inflector(
new CachedWordInflector(new RulesetInflector(
English\Rules::getSingularRuleset()
)),
new CachedWordInflector(new RulesetInflector(
English\Rules::getPluralRuleset()
))
);
Adding Languages
----------------
If you are interested in adding support for your language, take a look at the other languages defined in the
``Doctrine\Inflector\Rules`` namespace and the tests located in ``Doctrine\Tests\Inflector\Rules``. You can copy
one of the languages and update the rules for your language.
Once you have done this, send a pull request to the ``doctrine/inflector`` repository with the additions.
Custom Setup
============
If you want to setup custom singular and plural rules, you can configure these in the factory:
.. code-block:: php
use Doctrine\Inflector\InflectorFactory;
use Doctrine\Inflector\Rules\Pattern;
use Doctrine\Inflector\Rules\Patterns;
use Doctrine\Inflector\Rules\Ruleset;
use Doctrine\Inflector\Rules\Substitution;
use Doctrine\Inflector\Rules\Substitutions;
use Doctrine\Inflector\Rules\Transformation;
use Doctrine\Inflector\Rules\Transformations;
use Doctrine\Inflector\Rules\Word;
$inflector = InflectorFactory::create()
->withSingularRules(
new Ruleset(
new Transformations(
new Transformation(new Pattern('/^(bil)er$/i'), '\1'),
new Transformation(new Pattern('/^(inflec|contribu)tors$/i'), '\1ta')
),
new Patterns(new Pattern('singulars')),
new Substitutions(new Substitution(new Word('spins'), new Word('spinor')))
)
)
->withPluralRules(
new Ruleset(
new Transformations(
new Transformation(new Pattern('^(bil)er$'), '\1'),
new Transformation(new Pattern('^(inflec|contribu)tors$'), '\1ta')
),
new Patterns(new Pattern('noflect'), new Pattern('abtuse')),
new Substitutions(
new Substitution(new Word('amaze'), new Word('amazable')),
new Substitution(new Word('phone'), new Word('phonezes'))
)
)
)
->build();
No operation inflector
----------------------
The ``Doctrine\Inflector\NoopWordInflector`` may be used to configure an inflector that doesn't perform any operation for
pluralization and/or singularization. If will simply return the input as output.
This is an implementation of the `Null Object design pattern <https://sourcemaking.com/design_patterns/null_object>`_.
.. code-block:: php
use Doctrine\Inflector\Inflector;
use Doctrine\Inflector\NoopWordInflector;
$inflector = new Inflector(new NoopWordInflector(), new NoopWordInflector());
Tableize
========
Converts ``ModelName`` to ``model_name``:
.. code-block:: php
echo $inflector->tableize('ModelName'); // model_name
Classify
========
Converts ``model_name`` to ``ModelName``:
.. code-block:: php
echo $inflector->classify('model_name'); // ModelName
Camelize
========
This method uses `Classify`_ and then converts the first character to lowercase:
.. code-block:: php
echo $inflector->camelize('model_name'); // modelName
Capitalize
==========
Takes a string and capitalizes all of the words, like PHP's built-in
``ucwords`` function. This extends that behavior, however, by allowing the
word delimiters to be configured, rather than only separating on
whitespace.
Here is an example:
.. code-block:: php
$string = 'top-o-the-morning to all_of_you!';
echo $inflector->capitalize($string); // Top-O-The-Morning To All_of_you!
echo $inflector->capitalize($string, '-_ '); // Top-O-The-Morning To All_Of_You!
Pluralize
=========
Returns a word in plural form.
.. code-block:: php
echo $inflector->pluralize('browser'); // browsers
Singularize
===========
Returns a word in singular form.
.. code-block:: php
echo $inflector->singularize('browsers'); // browser
Urlize
======
Generate a URL friendly string from a string of text:
.. code-block:: php
echo $inflector->urlize('My first blog post'); // my-first-blog-post
Unaccent
========
You can unaccent a string of text using the ``unaccent()`` method:
.. code-block:: php
echo $inflector->unaccent('año'); // ano
Legacy API
==========
The API present in Inflector 1.x is still available, but will be deprecated in a future release and dropped for 3.0.
Support for languages other than English is available in the 2.0 API only.
Acknowledgements
================
The language rules in this library have been adapted from several different sources, including but not limited to:
- `Ruby On Rails Inflector <http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html>`_
- `ICanBoogie Inflector <https://github.com/ICanBoogie/Inflector>`_
- `CakePHP Inflector <https://book.cakephp.org/3.0/en/core-libraries/inflector.html>`_

View File

@ -0,0 +1,20 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector;
class CachedWordInflector implements WordInflector
{
/** @var WordInflector */
private $wordInflector;
/** @var string[] */
private $cache = [];
public function __construct(WordInflector $wordInflector)
{
$this->wordInflector = $wordInflector;
}
public function inflect(string $word) : string
{
return $this->cache[$word] ?? ($this->cache[$word] = $this->wordInflector->inflect($word));
}
}

View File

@ -0,0 +1,45 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
use function array_unshift;
abstract class GenericLanguageInflectorFactory implements LanguageInflectorFactory
{
/** @var Ruleset[] */
private $singularRulesets = [];
/** @var Ruleset[] */
private $pluralRulesets = [];
public final function __construct()
{
$this->singularRulesets[] = $this->getSingularRuleset();
$this->pluralRulesets[] = $this->getPluralRuleset();
}
public final function build() : Inflector
{
return new Inflector(new CachedWordInflector(new RulesetInflector(...$this->singularRulesets)), new CachedWordInflector(new RulesetInflector(...$this->pluralRulesets)));
}
public final function withSingularRules(?Ruleset $singularRules, bool $reset = \false) : LanguageInflectorFactory
{
if ($reset) {
$this->singularRulesets = [];
}
if ($singularRules instanceof Ruleset) {
array_unshift($this->singularRulesets, $singularRules);
}
return $this;
}
public final function withPluralRules(?Ruleset $pluralRules, bool $reset = \false) : LanguageInflectorFactory
{
if ($reset) {
$this->pluralRulesets = [];
}
if ($pluralRules instanceof Ruleset) {
array_unshift($this->pluralRulesets, $pluralRules);
}
return $this;
}
protected abstract function getSingularRuleset() : Ruleset;
protected abstract function getPluralRuleset() : Ruleset;
}

View File

@ -0,0 +1,204 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector;
use RuntimeException;
use function chr;
use function function_exists;
use function lcfirst;
use function mb_strtolower;
use function ord;
use function preg_match;
use function preg_replace;
use function sprintf;
use function str_replace;
use function strlen;
use function strtolower;
use function strtr;
use function trim;
use function ucwords;
class Inflector
{
private const ACCENTED_CHARACTERS = ['À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'Ae', 'Æ' => 'Ae', 'Å' => 'Aa', 'æ' => 'a', 'Ç' => 'C', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'Oe', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'Ue', 'Ý' => 'Y', 'ß' => 'ss', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'ae', 'å' => 'aa', 'ç' => 'c', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'oe', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'ue', 'ý' => 'y', 'ÿ' => 'y', 'Ā' => 'A', 'ā' => 'a', 'Ă' => 'A', 'ă' => 'a', 'Ą' => 'A', 'ą' => 'a', 'Ć' => 'C', 'ć' => 'c', 'Ĉ' => 'C', 'ĉ' => 'c', 'Ċ' => 'C', 'ċ' => 'c', 'Č' => 'C', 'č' => 'c', 'Ď' => 'D', 'ď' => 'd', 'Đ' => 'D', 'đ' => 'd', 'Ē' => 'E', 'ē' => 'e', 'Ĕ' => 'E', 'ĕ' => 'e', 'Ė' => 'E', 'ė' => 'e', 'Ę' => 'E', 'ę' => 'e', 'Ě' => 'E', 'ě' => 'e', 'Ĝ' => 'G', 'ĝ' => 'g', 'Ğ' => 'G', 'ğ' => 'g', 'Ġ' => 'G', 'ġ' => 'g', 'Ģ' => 'G', 'ģ' => 'g', 'Ĥ' => 'H', 'ĥ' => 'h', 'Ħ' => 'H', 'ħ' => 'h', 'Ĩ' => 'I', 'ĩ' => 'i', 'Ī' => 'I', 'ī' => 'i', 'Ĭ' => 'I', 'ĭ' => 'i', 'Į' => 'I', 'į' => 'i', 'İ' => 'I', 'ı' => 'i', 'IJ' => 'IJ', 'ij' => 'ij', 'Ĵ' => 'J', 'ĵ' => 'j', 'Ķ' => 'K', 'ķ' => 'k', 'ĸ' => 'k', 'Ĺ' => 'L', 'ĺ' => 'l', 'Ļ' => 'L', 'ļ' => 'l', 'Ľ' => 'L', 'ľ' => 'l', 'Ŀ' => 'L', 'ŀ' => 'l', 'Ł' => 'L', 'ł' => 'l', 'Ń' => 'N', 'ń' => 'n', 'Ņ' => 'N', 'ņ' => 'n', 'Ň' => 'N', 'ň' => 'n', 'ʼn' => 'N', 'Ŋ' => 'n', 'ŋ' => 'N', 'Ō' => 'O', 'ō' => 'o', 'Ŏ' => 'O', 'ŏ' => 'o', 'Ő' => 'O', 'ő' => 'o', 'Œ' => 'OE', 'œ' => 'oe', 'Ø' => 'O', 'ø' => 'o', 'Ŕ' => 'R', 'ŕ' => 'r', 'Ŗ' => 'R', 'ŗ' => 'r', 'Ř' => 'R', 'ř' => 'r', 'Ś' => 'S', 'ś' => 's', 'Ŝ' => 'S', 'ŝ' => 's', 'Ş' => 'S', 'ş' => 's', 'Š' => 'S', 'š' => 's', 'Ţ' => 'T', 'ţ' => 't', 'Ť' => 'T', 'ť' => 't', 'Ŧ' => 'T', 'ŧ' => 't', 'Ũ' => 'U', 'ũ' => 'u', 'Ū' => 'U', 'ū' => 'u', 'Ŭ' => 'U', 'ŭ' => 'u', 'Ů' => 'U', 'ů' => 'u', 'Ű' => 'U', 'ű' => 'u', 'Ų' => 'U', 'ų' => 'u', 'Ŵ' => 'W', 'ŵ' => 'w', 'Ŷ' => 'Y', 'ŷ' => 'y', 'Ÿ' => 'Y', 'Ź' => 'Z', 'ź' => 'z', 'Ż' => 'Z', 'ż' => 'z', 'Ž' => 'Z', 'ž' => 'z', 'ſ' => 's', '€' => 'E', '£' => ''];
/** @var WordInflector */
private $singularizer;
/** @var WordInflector */
private $pluralizer;
public function __construct(WordInflector $singularizer, WordInflector $pluralizer)
{
$this->singularizer = $singularizer;
$this->pluralizer = $pluralizer;
}
/**
* Converts a word into the format for a Doctrine table name. Converts 'ModelName' to 'model_name'.
*/
public function tableize(string $word) : string
{
$tableized = preg_replace('~(?<=\\w)([A-Z])~u', '_$1', $word);
if ($tableized === null) {
throw new RuntimeException(sprintf('preg_replace returned null for value "%s"', $word));
}
return mb_strtolower($tableized);
}
/**
* Converts a word into the format for a Doctrine class name. Converts 'table_name' to 'TableName'.
*/
public function classify(string $word) : string
{
return str_replace([' ', '_', '-'], '', ucwords($word, ' _-'));
}
/**
* Camelizes a word. This uses the classify() method and turns the first character to lowercase.
*/
public function camelize(string $word) : string
{
return lcfirst($this->classify($word));
}
/**
* Uppercases words with configurable delimiters between words.
*
* Takes a string and capitalizes all of the words, like PHP's built-in
* ucwords function. This extends that behavior, however, by allowing the
* word delimiters to be configured, rather than only separating on
* whitespace.
*
* Here is an example:
* <code>
* <?php
* $string = 'top-o-the-morning to all_of_you!';
* echo $inflector->capitalize($string);
* // Top-O-The-Morning To All_of_you!
*
* echo $inflector->capitalize($string, '-_ ');
* // Top-O-The-Morning To All_Of_You!
* ?>
* </code>
*
* @param string $string The string to operate on.
* @param string $delimiters A list of word separators.
*
* @return string The string with all delimiter-separated words capitalized.
*/
public function capitalize(string $string, string $delimiters = " \n\t\r\x00\v-") : string
{
return ucwords($string, $delimiters);
}
/**
* Checks if the given string seems like it has utf8 characters in it.
*
* @param string $string The string to check for utf8 characters in.
*/
public function seemsUtf8(string $string) : bool
{
for ($i = 0; $i < strlen($string); $i++) {
if (ord($string[$i]) < 0x80) {
continue;
// 0bbbbbbb
}
if ((ord($string[$i]) & 0xe0) === 0xc0) {
$n = 1;
// 110bbbbb
} elseif ((ord($string[$i]) & 0xf0) === 0xe0) {
$n = 2;
// 1110bbbb
} elseif ((ord($string[$i]) & 0xf8) === 0xf0) {
$n = 3;
// 11110bbb
} elseif ((ord($string[$i]) & 0xfc) === 0xf8) {
$n = 4;
// 111110bb
} elseif ((ord($string[$i]) & 0xfe) === 0xfc) {
$n = 5;
// 1111110b
} else {
return \false;
// Does not match any model
}
for ($j = 0; $j < $n; $j++) {
// n bytes matching 10bbbbbb follow ?
if (++$i === strlen($string) || (ord($string[$i]) & 0xc0) !== 0x80) {
return \false;
}
}
}
return \true;
}
/**
* Remove any illegal characters, accents, etc.
*
* @param string $string String to unaccent
*
* @return string Unaccented string
*/
public function unaccent(string $string) : string
{
if (preg_match('/[\\x80-\\xff]/', $string) === \false) {
return $string;
}
if ($this->seemsUtf8($string)) {
$string = strtr($string, self::ACCENTED_CHARACTERS);
} else {
$characters = [];
// Assume ISO-8859-1 if not UTF-8
$characters['in'] = chr(128) . chr(131) . chr(138) . chr(142) . chr(154) . chr(158) . chr(159) . chr(162) . chr(165) . chr(181) . chr(192) . chr(193) . chr(194) . chr(195) . chr(196) . chr(197) . chr(199) . chr(200) . chr(201) . chr(202) . chr(203) . chr(204) . chr(205) . chr(206) . chr(207) . chr(209) . chr(210) . chr(211) . chr(212) . chr(213) . chr(214) . chr(216) . chr(217) . chr(218) . chr(219) . chr(220) . chr(221) . chr(224) . chr(225) . chr(226) . chr(227) . chr(228) . chr(229) . chr(231) . chr(232) . chr(233) . chr(234) . chr(235) . chr(236) . chr(237) . chr(238) . chr(239) . chr(241) . chr(242) . chr(243) . chr(244) . chr(245) . chr(246) . chr(248) . chr(249) . chr(250) . chr(251) . chr(252) . chr(253) . chr(255);
$characters['out'] = 'EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy';
$string = strtr($string, $characters['in'], $characters['out']);
$doubleChars = [];
$doubleChars['in'] = [chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254)];
$doubleChars['out'] = ['OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'];
$string = str_replace($doubleChars['in'], $doubleChars['out'], $string);
}
return $string;
}
/**
* Convert any passed string to a url friendly string.
* Converts 'My first blog post' to 'my-first-blog-post'
*
* @param string $string String to urlize.
*
* @return string Urlized string.
*/
public function urlize(string $string) : string
{
// Remove all non url friendly characters with the unaccent function
$unaccented = $this->unaccent($string);
if (function_exists('mb_strtolower')) {
$lowered = mb_strtolower($unaccented);
} else {
$lowered = strtolower($unaccented);
}
$replacements = ['/\\W/' => ' ', '/([A-Z]+)([A-Z][a-z])/' => 'RectorPrefix202310\\1_\\2', '/([a-z\\d])([A-Z])/' => 'RectorPrefix202310\\1_\\2', '/[^A-Z^a-z^0-9^\\/]+/' => '-'];
$urlized = $lowered;
foreach ($replacements as $pattern => $replacement) {
$replaced = preg_replace($pattern, $replacement, $urlized);
if ($replaced === null) {
throw new RuntimeException(sprintf('preg_replace returned null for value "%s"', $urlized));
}
$urlized = $replaced;
}
return trim($urlized, '-');
}
/**
* Returns a word in singular form.
*
* @param string $word The word in plural form.
*
* @return string The word in singular form.
*/
public function singularize(string $word) : string
{
return $this->singularizer->inflect($word);
}
/**
* Returns a word in plural form.
*
* @param string $word The word in singular form.
*
* @return string The word in plural form.
*/
public function pluralize(string $word) : string
{
return $this->pluralizer->inflect($word);
}
}

View File

@ -0,0 +1,39 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector;
use RectorPrefix202310\Doctrine\Inflector\Rules\English;
use RectorPrefix202310\Doctrine\Inflector\Rules\French;
use RectorPrefix202310\Doctrine\Inflector\Rules\NorwegianBokmal;
use RectorPrefix202310\Doctrine\Inflector\Rules\Portuguese;
use RectorPrefix202310\Doctrine\Inflector\Rules\Spanish;
use RectorPrefix202310\Doctrine\Inflector\Rules\Turkish;
use InvalidArgumentException;
use function sprintf;
final class InflectorFactory
{
public static function create() : LanguageInflectorFactory
{
return self::createForLanguage(Language::ENGLISH);
}
public static function createForLanguage(string $language) : LanguageInflectorFactory
{
switch ($language) {
case Language::ENGLISH:
return new English\InflectorFactory();
case Language::FRENCH:
return new French\InflectorFactory();
case Language::NORWEGIAN_BOKMAL:
return new NorwegianBokmal\InflectorFactory();
case Language::PORTUGUESE:
return new Portuguese\InflectorFactory();
case Language::SPANISH:
return new Spanish\InflectorFactory();
case Language::TURKISH:
return new Turkish\InflectorFactory();
default:
throw new InvalidArgumentException(sprintf('Language "%s" is not supported.', $language));
}
}
}

View File

@ -0,0 +1,17 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector;
final class Language
{
public const ENGLISH = 'english';
public const FRENCH = 'french';
public const NORWEGIAN_BOKMAL = 'norwegian-bokmal';
public const PORTUGUESE = 'portuguese';
public const SPANISH = 'spanish';
public const TURKISH = 'turkish';
private function __construct()
{
}
}

View File

@ -0,0 +1,29 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
interface LanguageInflectorFactory
{
/**
* Applies custom rules for singularisation
*
* @param bool $reset If true, will unset default inflections for all new rules
*
* @return $this
*/
public function withSingularRules(?Ruleset $singularRules, bool $reset = \false) : self;
/**
* Applies custom rules for pluralisation
*
* @param bool $reset If true, will unset default inflections for all new rules
*
* @return $this
*/
public function withPluralRules(?Ruleset $pluralRules, bool $reset = \false) : self;
/**
* Builds the inflector instance with all applicable rules
*/
public function build() : Inflector;
}

View File

@ -0,0 +1,12 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector;
class NoopWordInflector implements WordInflector
{
public function inflect(string $word) : string
{
return $word;
}
}

View File

@ -0,0 +1,177 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\English;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitution;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformation;
use RectorPrefix202310\Doctrine\Inflector\Rules\Word;
class Inflectible
{
/** @return Transformation[] */
public static function getSingular() : iterable
{
(yield new Transformation(new Pattern('(s)tatuses$'), 'RectorPrefix202310\\1\\2tatus'));
(yield new Transformation(new Pattern('(s)tatus$'), 'RectorPrefix202310\\1\\2tatus'));
(yield new Transformation(new Pattern('(c)ampus$'), 'RectorPrefix202310\\1\\2ampus'));
(yield new Transformation(new Pattern('^(.*)(menu)s$'), 'RectorPrefix202310\\1\\2'));
(yield new Transformation(new Pattern('(quiz)zes$'), '\\1'));
(yield new Transformation(new Pattern('(matr)ices$'), '\\1ix'));
(yield new Transformation(new Pattern('(vert|ind)ices$'), '\\1ex'));
(yield new Transformation(new Pattern('^(ox)en'), '\\1'));
(yield new Transformation(new Pattern('(alias)(es)*$'), '\\1'));
(yield new Transformation(new Pattern('(buffal|her|potat|tomat|volcan)oes$'), '\\1o'));
(yield new Transformation(new Pattern('(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$'), '\\1us'));
(yield new Transformation(new Pattern('([ftw]ax)es'), '\\1'));
(yield new Transformation(new Pattern('(analys|ax|cris|test|thes)es$'), '\\1is'));
(yield new Transformation(new Pattern('(shoe|slave)s$'), '\\1'));
(yield new Transformation(new Pattern('(o)es$'), '\\1'));
(yield new Transformation(new Pattern('ouses$'), 'ouse'));
(yield new Transformation(new Pattern('([^a])uses$'), '\\1us'));
(yield new Transformation(new Pattern('([m|l])ice$'), '\\1ouse'));
(yield new Transformation(new Pattern('(x|ch|ss|sh)es$'), '\\1'));
(yield new Transformation(new Pattern('(m)ovies$'), 'RectorPrefix202310\\1\\2ovie'));
(yield new Transformation(new Pattern('(s)eries$'), 'RectorPrefix202310\\1\\2eries'));
(yield new Transformation(new Pattern('([^aeiouy]|qu)ies$'), '\\1y'));
(yield new Transformation(new Pattern('([lr])ves$'), '\\1f'));
(yield new Transformation(new Pattern('(tive)s$'), '\\1'));
(yield new Transformation(new Pattern('(hive)s$'), '\\1'));
(yield new Transformation(new Pattern('(drive)s$'), '\\1'));
(yield new Transformation(new Pattern('(dive)s$'), '\\1'));
(yield new Transformation(new Pattern('(olive)s$'), '\\1'));
(yield new Transformation(new Pattern('([^fo])ves$'), '\\1fe'));
(yield new Transformation(new Pattern('(^analy)ses$'), '\\1sis'));
(yield new Transformation(new Pattern('(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$'), 'RectorPrefix202310\\1\\2sis'));
(yield new Transformation(new Pattern('(tax)a$'), '\\1on'));
(yield new Transformation(new Pattern('(c)riteria$'), '\\1riterion'));
(yield new Transformation(new Pattern('([ti])a$'), '\\1um'));
(yield new Transformation(new Pattern('(p)eople$'), 'RectorPrefix202310\\1\\2erson'));
(yield new Transformation(new Pattern('(m)en$'), '\\1an'));
(yield new Transformation(new Pattern('(c)hildren$'), 'RectorPrefix202310\\1\\2hild'));
(yield new Transformation(new Pattern('(f)eet$'), '\\1oot'));
(yield new Transformation(new Pattern('(n)ews$'), 'RectorPrefix202310\\1\\2ews'));
(yield new Transformation(new Pattern('eaus$'), 'eau'));
(yield new Transformation(new Pattern('^tights$'), 'tights'));
(yield new Transformation(new Pattern('^shorts$'), 'shorts'));
(yield new Transformation(new Pattern('s$'), ''));
}
/** @return Transformation[] */
public static function getPlural() : iterable
{
(yield new Transformation(new Pattern('(s)tatus$'), 'RectorPrefix202310\\1\\2tatuses'));
(yield new Transformation(new Pattern('(quiz)$'), '\\1zes'));
(yield new Transformation(new Pattern('^(ox)$'), 'RectorPrefix202310\\1\\2en'));
(yield new Transformation(new Pattern('([m|l])ouse$'), '\\1ice'));
(yield new Transformation(new Pattern('(matr|vert|ind)(ix|ex)$'), '\\1ices'));
(yield new Transformation(new Pattern('(x|ch|ss|sh)$'), '\\1es'));
(yield new Transformation(new Pattern('([^aeiouy]|qu)y$'), '\\1ies'));
(yield new Transformation(new Pattern('(hive|gulf)$'), '\\1s'));
(yield new Transformation(new Pattern('(?:([^f])fe|([lr])f)$'), 'RectorPrefix202310\\1\\2ves'));
(yield new Transformation(new Pattern('sis$'), 'ses'));
(yield new Transformation(new Pattern('([ti])um$'), '\\1a'));
(yield new Transformation(new Pattern('(tax)on$'), '\\1a'));
(yield new Transformation(new Pattern('(c)riterion$'), '\\1riteria'));
(yield new Transformation(new Pattern('(p)erson$'), '\\1eople'));
(yield new Transformation(new Pattern('(m)an$'), '\\1en'));
(yield new Transformation(new Pattern('(c)hild$'), '\\1hildren'));
(yield new Transformation(new Pattern('(f)oot$'), '\\1eet'));
(yield new Transformation(new Pattern('(buffal|her|potat|tomat|volcan)o$'), 'RectorPrefix202310\\1\\2oes'));
(yield new Transformation(new Pattern('(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$'), '\\1i'));
(yield new Transformation(new Pattern('us$'), 'uses'));
(yield new Transformation(new Pattern('(alias)$'), '\\1es'));
(yield new Transformation(new Pattern('(analys|ax|cris|test|thes)is$'), '\\1es'));
(yield new Transformation(new Pattern('s$'), 's'));
(yield new Transformation(new Pattern('^$'), ''));
(yield new Transformation(new Pattern('$'), 's'));
}
/** @return Substitution[] */
public static function getIrregular() : iterable
{
(yield new Substitution(new Word('atlas'), new Word('atlases')));
(yield new Substitution(new Word('axe'), new Word('axes')));
(yield new Substitution(new Word('beef'), new Word('beefs')));
(yield new Substitution(new Word('blouse'), new Word('blouses')));
(yield new Substitution(new Word('brother'), new Word('brothers')));
(yield new Substitution(new Word('cafe'), new Word('cafes')));
(yield new Substitution(new Word('cave'), new Word('caves')));
(yield new Substitution(new Word('chateau'), new Word('chateaux')));
(yield new Substitution(new Word('niveau'), new Word('niveaux')));
(yield new Substitution(new Word('child'), new Word('children')));
(yield new Substitution(new Word('canvas'), new Word('canvases')));
(yield new Substitution(new Word('cookie'), new Word('cookies')));
(yield new Substitution(new Word('corpus'), new Word('corpuses')));
(yield new Substitution(new Word('cow'), new Word('cows')));
(yield new Substitution(new Word('criterion'), new Word('criteria')));
(yield new Substitution(new Word('curriculum'), new Word('curricula')));
(yield new Substitution(new Word('demo'), new Word('demos')));
(yield new Substitution(new Word('domino'), new Word('dominoes')));
(yield new Substitution(new Word('echo'), new Word('echoes')));
(yield new Substitution(new Word('foot'), new Word('feet')));
(yield new Substitution(new Word('fungus'), new Word('fungi')));
(yield new Substitution(new Word('ganglion'), new Word('ganglions')));
(yield new Substitution(new Word('gas'), new Word('gases')));
(yield new Substitution(new Word('genie'), new Word('genies')));
(yield new Substitution(new Word('genus'), new Word('genera')));
(yield new Substitution(new Word('goose'), new Word('geese')));
(yield new Substitution(new Word('graffito'), new Word('graffiti')));
(yield new Substitution(new Word('hippopotamus'), new Word('hippopotami')));
(yield new Substitution(new Word('hoof'), new Word('hoofs')));
(yield new Substitution(new Word('human'), new Word('humans')));
(yield new Substitution(new Word('iris'), new Word('irises')));
(yield new Substitution(new Word('larva'), new Word('larvae')));
(yield new Substitution(new Word('leaf'), new Word('leaves')));
(yield new Substitution(new Word('lens'), new Word('lenses')));
(yield new Substitution(new Word('loaf'), new Word('loaves')));
(yield new Substitution(new Word('man'), new Word('men')));
(yield new Substitution(new Word('medium'), new Word('media')));
(yield new Substitution(new Word('memorandum'), new Word('memoranda')));
(yield new Substitution(new Word('money'), new Word('monies')));
(yield new Substitution(new Word('mongoose'), new Word('mongooses')));
(yield new Substitution(new Word('motto'), new Word('mottoes')));
(yield new Substitution(new Word('move'), new Word('moves')));
(yield new Substitution(new Word('mythos'), new Word('mythoi')));
(yield new Substitution(new Word('niche'), new Word('niches')));
(yield new Substitution(new Word('nucleus'), new Word('nuclei')));
(yield new Substitution(new Word('numen'), new Word('numina')));
(yield new Substitution(new Word('occiput'), new Word('occiputs')));
(yield new Substitution(new Word('octopus'), new Word('octopuses')));
(yield new Substitution(new Word('opus'), new Word('opuses')));
(yield new Substitution(new Word('ox'), new Word('oxen')));
(yield new Substitution(new Word('passerby'), new Word('passersby')));
(yield new Substitution(new Word('penis'), new Word('penises')));
(yield new Substitution(new Word('person'), new Word('people')));
(yield new Substitution(new Word('plateau'), new Word('plateaux')));
(yield new Substitution(new Word('runner-up'), new Word('runners-up')));
(yield new Substitution(new Word('safe'), new Word('safes')));
(yield new Substitution(new Word('sex'), new Word('sexes')));
(yield new Substitution(new Word('sieve'), new Word('sieves')));
(yield new Substitution(new Word('soliloquy'), new Word('soliloquies')));
(yield new Substitution(new Word('son-in-law'), new Word('sons-in-law')));
(yield new Substitution(new Word('syllabus'), new Word('syllabi')));
(yield new Substitution(new Word('testis'), new Word('testes')));
(yield new Substitution(new Word('thief'), new Word('thieves')));
(yield new Substitution(new Word('tooth'), new Word('teeth')));
(yield new Substitution(new Word('tornado'), new Word('tornadoes')));
(yield new Substitution(new Word('trilby'), new Word('trilbys')));
(yield new Substitution(new Word('turf'), new Word('turfs')));
(yield new Substitution(new Word('valve'), new Word('valves')));
(yield new Substitution(new Word('volcano'), new Word('volcanoes')));
(yield new Substitution(new Word('abuse'), new Word('abuses')));
(yield new Substitution(new Word('avalanche'), new Word('avalanches')));
(yield new Substitution(new Word('cache'), new Word('caches')));
(yield new Substitution(new Word('criterion'), new Word('criteria')));
(yield new Substitution(new Word('curve'), new Word('curves')));
(yield new Substitution(new Word('emphasis'), new Word('emphases')));
(yield new Substitution(new Word('foe'), new Word('foes')));
(yield new Substitution(new Word('grave'), new Word('graves')));
(yield new Substitution(new Word('hoax'), new Word('hoaxes')));
(yield new Substitution(new Word('medium'), new Word('media')));
(yield new Substitution(new Word('neurosis'), new Word('neuroses')));
(yield new Substitution(new Word('save'), new Word('saves')));
(yield new Substitution(new Word('wave'), new Word('waves')));
(yield new Substitution(new Word('oasis'), new Word('oases')));
(yield new Substitution(new Word('valve'), new Word('valves')));
(yield new Substitution(new Word('zombie'), new Word('zombies')));
}
}

View File

@ -0,0 +1,18 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\English;
use RectorPrefix202310\Doctrine\Inflector\GenericLanguageInflectorFactory;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset() : Ruleset
{
return Rules::getSingularRuleset();
}
protected function getPluralRuleset() : Ruleset
{
return Rules::getPluralRuleset();
}
}

View File

@ -0,0 +1,20 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\English;
use RectorPrefix202310\Doctrine\Inflector\Rules\Patterns;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitutions;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformations;
final class Rules
{
public static function getSingularRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getSingular()), new Patterns(...Uninflected::getSingular()), (new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions());
}
public static function getPluralRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()));
}
}

View File

@ -0,0 +1,183 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\English;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
final class Uninflected
{
/** @return Pattern[] */
public static function getSingular() : iterable
{
yield from self::getDefault();
(yield new Pattern('.*ss'));
(yield new Pattern('clothes'));
(yield new Pattern('data'));
(yield new Pattern('fascia'));
(yield new Pattern('fuchsia'));
(yield new Pattern('galleria'));
(yield new Pattern('mafia'));
(yield new Pattern('militia'));
(yield new Pattern('pants'));
(yield new Pattern('petunia'));
(yield new Pattern('sepia'));
(yield new Pattern('trivia'));
(yield new Pattern('utopia'));
}
/** @return Pattern[] */
public static function getPlural() : iterable
{
yield from self::getDefault();
(yield new Pattern('people'));
(yield new Pattern('trivia'));
(yield new Pattern('\\w+ware$'));
(yield new Pattern('media'));
}
/** @return Pattern[] */
private static function getDefault() : iterable
{
(yield new Pattern('\\w+media'));
(yield new Pattern('advice'));
(yield new Pattern('aircraft'));
(yield new Pattern('amoyese'));
(yield new Pattern('art'));
(yield new Pattern('audio'));
(yield new Pattern('baggage'));
(yield new Pattern('bison'));
(yield new Pattern('borghese'));
(yield new Pattern('bream'));
(yield new Pattern('breeches'));
(yield new Pattern('britches'));
(yield new Pattern('buffalo'));
(yield new Pattern('butter'));
(yield new Pattern('cantus'));
(yield new Pattern('carp'));
(yield new Pattern('cattle'));
(yield new Pattern('chassis'));
(yield new Pattern('clippers'));
(yield new Pattern('clothing'));
(yield new Pattern('coal'));
(yield new Pattern('cod'));
(yield new Pattern('coitus'));
(yield new Pattern('compensation'));
(yield new Pattern('congoese'));
(yield new Pattern('contretemps'));
(yield new Pattern('coreopsis'));
(yield new Pattern('corps'));
(yield new Pattern('cotton'));
(yield new Pattern('data'));
(yield new Pattern('debris'));
(yield new Pattern('deer'));
(yield new Pattern('diabetes'));
(yield new Pattern('djinn'));
(yield new Pattern('education'));
(yield new Pattern('eland'));
(yield new Pattern('elk'));
(yield new Pattern('emoji'));
(yield new Pattern('equipment'));
(yield new Pattern('evidence'));
(yield new Pattern('faroese'));
(yield new Pattern('feedback'));
(yield new Pattern('fish'));
(yield new Pattern('flounder'));
(yield new Pattern('flour'));
(yield new Pattern('foochowese'));
(yield new Pattern('food'));
(yield new Pattern('furniture'));
(yield new Pattern('gallows'));
(yield new Pattern('genevese'));
(yield new Pattern('genoese'));
(yield new Pattern('gilbertese'));
(yield new Pattern('gold'));
(yield new Pattern('headquarters'));
(yield new Pattern('herpes'));
(yield new Pattern('hijinks'));
(yield new Pattern('homework'));
(yield new Pattern('hottentotese'));
(yield new Pattern('impatience'));
(yield new Pattern('information'));
(yield new Pattern('innings'));
(yield new Pattern('jackanapes'));
(yield new Pattern('jeans'));
(yield new Pattern('jedi'));
(yield new Pattern('kin'));
(yield new Pattern('kiplingese'));
(yield new Pattern('knowledge'));
(yield new Pattern('kongoese'));
(yield new Pattern('leather'));
(yield new Pattern('love'));
(yield new Pattern('lucchese'));
(yield new Pattern('luggage'));
(yield new Pattern('mackerel'));
(yield new Pattern('Maltese'));
(yield new Pattern('management'));
(yield new Pattern('metadata'));
(yield new Pattern('mews'));
(yield new Pattern('money'));
(yield new Pattern('moose'));
(yield new Pattern('mumps'));
(yield new Pattern('music'));
(yield new Pattern('nankingese'));
(yield new Pattern('news'));
(yield new Pattern('nexus'));
(yield new Pattern('niasese'));
(yield new Pattern('nutrition'));
(yield new Pattern('offspring'));
(yield new Pattern('oil'));
(yield new Pattern('patience'));
(yield new Pattern('pekingese'));
(yield new Pattern('piedmontese'));
(yield new Pattern('pincers'));
(yield new Pattern('pistoiese'));
(yield new Pattern('plankton'));
(yield new Pattern('pliers'));
(yield new Pattern('pokemon'));
(yield new Pattern('police'));
(yield new Pattern('polish'));
(yield new Pattern('portuguese'));
(yield new Pattern('proceedings'));
(yield new Pattern('progress'));
(yield new Pattern('rabies'));
(yield new Pattern('rain'));
(yield new Pattern('research'));
(yield new Pattern('rhinoceros'));
(yield new Pattern('rice'));
(yield new Pattern('salmon'));
(yield new Pattern('sand'));
(yield new Pattern('sarawakese'));
(yield new Pattern('scissors'));
(yield new Pattern('sea[- ]bass'));
(yield new Pattern('series'));
(yield new Pattern('shavese'));
(yield new Pattern('shears'));
(yield new Pattern('sheep'));
(yield new Pattern('siemens'));
(yield new Pattern('silk'));
(yield new Pattern('sms'));
(yield new Pattern('soap'));
(yield new Pattern('social media'));
(yield new Pattern('spam'));
(yield new Pattern('species'));
(yield new Pattern('staff'));
(yield new Pattern('sugar'));
(yield new Pattern('swine'));
(yield new Pattern('talent'));
(yield new Pattern('toothpaste'));
(yield new Pattern('traffic'));
(yield new Pattern('travel'));
(yield new Pattern('trousers'));
(yield new Pattern('trout'));
(yield new Pattern('tuna'));
(yield new Pattern('us'));
(yield new Pattern('vermontese'));
(yield new Pattern('vinegar'));
(yield new Pattern('weather'));
(yield new Pattern('wenchowese'));
(yield new Pattern('wheat'));
(yield new Pattern('whiting'));
(yield new Pattern('wildebeest'));
(yield new Pattern('wood'));
(yield new Pattern('wool'));
(yield new Pattern('yengeese'));
}
}

View File

@ -0,0 +1,40 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\French;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitution;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformation;
use RectorPrefix202310\Doctrine\Inflector\Rules\Word;
class Inflectible
{
/** @return Transformation[] */
public static function getSingular() : iterable
{
(yield new Transformation(new Pattern('/(b|cor|ém|gemm|soupir|trav|vant|vitr)aux$/'), '\\1ail'));
(yield new Transformation(new Pattern('/ails$/'), 'ail'));
(yield new Transformation(new Pattern('/(journ|chev)aux$/'), '\\1al'));
(yield new Transformation(new Pattern('/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)x$/'), '\\1'));
(yield new Transformation(new Pattern('/s$/'), ''));
}
/** @return Transformation[] */
public static function getPlural() : iterable
{
(yield new Transformation(new Pattern('/(s|x|z)$/'), '\\1'));
(yield new Transformation(new Pattern('/(b|cor|ém|gemm|soupir|trav|vant|vitr)ail$/'), '\\1aux'));
(yield new Transformation(new Pattern('/ail$/'), 'ails'));
(yield new Transformation(new Pattern('/(chacal|carnaval|festival|récital)$/'), '\\1s'));
(yield new Transformation(new Pattern('/al$/'), 'aux'));
(yield new Transformation(new Pattern('/(bleu|émeu|landau|pneu|sarrau)$/'), '\\1s'));
(yield new Transformation(new Pattern('/(bijou|caillou|chou|genou|hibou|joujou|lieu|pou|au|eu|eau)$/'), '\\1x'));
(yield new Transformation(new Pattern('/$/'), 's'));
}
/** @return Substitution[] */
public static function getIrregular() : iterable
{
(yield new Substitution(new Word('monsieur'), new Word('messieurs')));
(yield new Substitution(new Word('madame'), new Word('mesdames')));
(yield new Substitution(new Word('mademoiselle'), new Word('mesdemoiselles')));
}
}

View File

@ -0,0 +1,18 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\French;
use RectorPrefix202310\Doctrine\Inflector\GenericLanguageInflectorFactory;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset() : Ruleset
{
return Rules::getSingularRuleset();
}
protected function getPluralRuleset() : Ruleset
{
return Rules::getPluralRuleset();
}
}

View File

@ -0,0 +1,20 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\French;
use RectorPrefix202310\Doctrine\Inflector\Rules\Patterns;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitutions;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformations;
final class Rules
{
public static function getSingularRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getSingular()), new Patterns(...Uninflected::getSingular()), (new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions());
}
public static function getPluralRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()));
}
}

View File

@ -0,0 +1,24 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\French;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
final class Uninflected
{
/** @return Pattern[] */
public static function getSingular() : iterable
{
yield from self::getDefault();
}
/** @return Pattern[] */
public static function getPlural() : iterable
{
yield from self::getDefault();
}
/** @return Pattern[] */
private static function getDefault() : iterable
{
(yield new Pattern(''));
}
}

View File

@ -0,0 +1,30 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\NorwegianBokmal;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitution;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformation;
use RectorPrefix202310\Doctrine\Inflector\Rules\Word;
class Inflectible
{
/** @return Transformation[] */
public static function getSingular() : iterable
{
(yield new Transformation(new Pattern('/re$/i'), 'r'));
(yield new Transformation(new Pattern('/er$/i'), ''));
}
/** @return Transformation[] */
public static function getPlural() : iterable
{
(yield new Transformation(new Pattern('/e$/i'), 'er'));
(yield new Transformation(new Pattern('/r$/i'), 're'));
(yield new Transformation(new Pattern('/$/'), 'er'));
}
/** @return Substitution[] */
public static function getIrregular() : iterable
{
(yield new Substitution(new Word('konto'), new Word('konti')));
}
}

View File

@ -0,0 +1,18 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\NorwegianBokmal;
use RectorPrefix202310\Doctrine\Inflector\GenericLanguageInflectorFactory;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset() : Ruleset
{
return Rules::getSingularRuleset();
}
protected function getPluralRuleset() : Ruleset
{
return Rules::getPluralRuleset();
}
}

View File

@ -0,0 +1,20 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\NorwegianBokmal;
use RectorPrefix202310\Doctrine\Inflector\Rules\Patterns;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitutions;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformations;
final class Rules
{
public static function getSingularRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getSingular()), new Patterns(...Uninflected::getSingular()), (new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions());
}
public static function getPluralRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()));
}
}

View File

@ -0,0 +1,26 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\NorwegianBokmal;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
final class Uninflected
{
/** @return Pattern[] */
public static function getSingular() : iterable
{
yield from self::getDefault();
}
/** @return Pattern[] */
public static function getPlural() : iterable
{
yield from self::getDefault();
}
/** @return Pattern[] */
private static function getDefault() : iterable
{
(yield new Pattern('barn'));
(yield new Pattern('fjell'));
(yield new Pattern('hus'));
}
}

View File

@ -0,0 +1,34 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules;
use function preg_match;
final class Pattern
{
/** @var string */
private $pattern;
/** @var string */
private $regex;
public function __construct(string $pattern)
{
$this->pattern = $pattern;
if (isset($this->pattern[0]) && $this->pattern[0] === '/') {
$this->regex = $this->pattern;
} else {
$this->regex = '/' . $this->pattern . '/i';
}
}
public function getPattern() : string
{
return $this->pattern;
}
public function getRegex() : string
{
return $this->regex;
}
public function matches(string $word) : bool
{
return preg_match($this->getRegex(), $word) === 1;
}
}

View File

@ -0,0 +1,27 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules;
use function array_map;
use function implode;
use function preg_match;
class Patterns
{
/** @var Pattern[] */
private $patterns;
/** @var string */
private $regex;
public function __construct(Pattern ...$patterns)
{
$this->patterns = $patterns;
$patterns = array_map(static function (Pattern $pattern) : string {
return $pattern->getPattern();
}, $this->patterns);
$this->regex = '/^(?:' . implode('|', $patterns) . ')$/i';
}
public function matches(string $word) : bool
{
return preg_match($this->regex, $word, $regs) === 1;
}
}

View File

@ -0,0 +1,94 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Portuguese;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitution;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformation;
use RectorPrefix202310\Doctrine\Inflector\Rules\Word;
class Inflectible
{
/** @return Transformation[] */
public static function getSingular() : iterable
{
(yield new Transformation(new Pattern('/^(g|)ases$/i'), '\\1ás'));
(yield new Transformation(new Pattern('/(japon|escoc|ingl|dinamarqu|fregu|portugu)eses$/i'), '\\1ês'));
(yield new Transformation(new Pattern('/(ae|ao|oe)s$/'), 'ao'));
(yield new Transformation(new Pattern('/(ãe|ão|õe)s$/'), 'ão'));
(yield new Transformation(new Pattern('/^(.*[^s]s)es$/i'), '\\1'));
(yield new Transformation(new Pattern('/sses$/i'), 'sse'));
(yield new Transformation(new Pattern('/ns$/i'), 'm'));
(yield new Transformation(new Pattern('/(r|t|f|v)is$/i'), '\\1il'));
(yield new Transformation(new Pattern('/uis$/i'), 'ul'));
(yield new Transformation(new Pattern('/ois$/i'), 'ol'));
(yield new Transformation(new Pattern('/eis$/i'), 'ei'));
(yield new Transformation(new Pattern('/éis$/i'), 'el'));
(yield new Transformation(new Pattern('/([^p])ais$/i'), '\\1al'));
(yield new Transformation(new Pattern('/(r|z)es$/i'), '\\1'));
(yield new Transformation(new Pattern('/^(á|gá)s$/i'), '\\1s'));
(yield new Transformation(new Pattern('/([^ê])s$/i'), '\\1'));
}
/** @return Transformation[] */
public static function getPlural() : iterable
{
(yield new Transformation(new Pattern('/^(alem|c|p)ao$/i'), '\\1aes'));
(yield new Transformation(new Pattern('/^(irm|m)ao$/i'), '\\1aos'));
(yield new Transformation(new Pattern('/ao$/i'), 'oes'));
(yield new Transformation(new Pattern('/^(alem|c|p)ão$/i'), '\\1ães'));
(yield new Transformation(new Pattern('/^(irm|m)ão$/i'), '\\1ãos'));
(yield new Transformation(new Pattern('/ão$/i'), 'ões'));
(yield new Transformation(new Pattern('/^(|g)ás$/i'), '\\1ases'));
(yield new Transformation(new Pattern('/^(japon|escoc|ingl|dinamarqu|fregu|portugu)ês$/i'), '\\1eses'));
(yield new Transformation(new Pattern('/m$/i'), 'ns'));
(yield new Transformation(new Pattern('/([^aeou])il$/i'), '\\1is'));
(yield new Transformation(new Pattern('/ul$/i'), 'uis'));
(yield new Transformation(new Pattern('/ol$/i'), 'ois'));
(yield new Transformation(new Pattern('/el$/i'), 'eis'));
(yield new Transformation(new Pattern('/al$/i'), 'ais'));
(yield new Transformation(new Pattern('/(z|r)$/i'), '\\1es'));
(yield new Transformation(new Pattern('/(s)$/i'), '\\1'));
(yield new Transformation(new Pattern('/$/'), 's'));
}
/** @return Substitution[] */
public static function getIrregular() : iterable
{
(yield new Substitution(new Word('abdomen'), new Word('abdomens')));
(yield new Substitution(new Word('alemão'), new Word('alemães')));
(yield new Substitution(new Word('artesã'), new Word('artesãos')));
(yield new Substitution(new Word('álcool'), new Word('álcoois')));
(yield new Substitution(new Word('árvore'), new Word('árvores')));
(yield new Substitution(new Word('bencão'), new Word('bencãos')));
(yield new Substitution(new Word('cão'), new Word('cães')));
(yield new Substitution(new Word('campus'), new Word('campi')));
(yield new Substitution(new Word('cadáver'), new Word('cadáveres')));
(yield new Substitution(new Word('capelão'), new Word('capelães')));
(yield new Substitution(new Word('capitão'), new Word('capitães')));
(yield new Substitution(new Word('chão'), new Word('chãos')));
(yield new Substitution(new Word('charlatão'), new Word('charlatães')));
(yield new Substitution(new Word('cidadão'), new Word('cidadãos')));
(yield new Substitution(new Word('consul'), new Word('consules')));
(yield new Substitution(new Word('cristão'), new Word('cristãos')));
(yield new Substitution(new Word('difícil'), new Word('difíceis')));
(yield new Substitution(new Word('email'), new Word('emails')));
(yield new Substitution(new Word('escrivão'), new Word('escrivães')));
(yield new Substitution(new Word('fóssil'), new Word('fósseis')));
(yield new Substitution(new Word('gás'), new Word('gases')));
(yield new Substitution(new Word('germens'), new Word('germen')));
(yield new Substitution(new Word('grão'), new Word('grãos')));
(yield new Substitution(new Word('hífen'), new Word('hífens')));
(yield new Substitution(new Word('irmão'), new Word('irmãos')));
(yield new Substitution(new Word('liquens'), new Word('liquen')));
(yield new Substitution(new Word('mal'), new Word('males')));
(yield new Substitution(new Word('mão'), new Word('mãos')));
(yield new Substitution(new Word('orfão'), new Word('orfãos')));
(yield new Substitution(new Word('país'), new Word('países')));
(yield new Substitution(new Word('pai'), new Word('pais')));
(yield new Substitution(new Word('pão'), new Word('pães')));
(yield new Substitution(new Word('projétil'), new Word('projéteis')));
(yield new Substitution(new Word('réptil'), new Word('répteis')));
(yield new Substitution(new Word('sacristão'), new Word('sacristães')));
(yield new Substitution(new Word('sotão'), new Word('sotãos')));
(yield new Substitution(new Word('tabelião'), new Word('tabeliães')));
}
}

View File

@ -0,0 +1,18 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Portuguese;
use RectorPrefix202310\Doctrine\Inflector\GenericLanguageInflectorFactory;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset() : Ruleset
{
return Rules::getSingularRuleset();
}
protected function getPluralRuleset() : Ruleset
{
return Rules::getPluralRuleset();
}
}

View File

@ -0,0 +1,20 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Portuguese;
use RectorPrefix202310\Doctrine\Inflector\Rules\Patterns;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitutions;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformations;
final class Rules
{
public static function getSingularRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getSingular()), new Patterns(...Uninflected::getSingular()), (new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions());
}
public static function getPluralRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()));
}
}

View File

@ -0,0 +1,28 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Portuguese;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
final class Uninflected
{
/** @return Pattern[] */
public static function getSingular() : iterable
{
yield from self::getDefault();
}
/** @return Pattern[] */
public static function getPlural() : iterable
{
yield from self::getDefault();
}
/** @return Pattern[] */
private static function getDefault() : iterable
{
(yield new Pattern('tórax'));
(yield new Pattern('tênis'));
(yield new Pattern('ônibus'));
(yield new Pattern('lápis'));
(yield new Pattern('fênix'));
}
}

View File

@ -0,0 +1,32 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules;
class Ruleset
{
/** @var Transformations */
private $regular;
/** @var Patterns */
private $uninflected;
/** @var Substitutions */
private $irregular;
public function __construct(Transformations $regular, Patterns $uninflected, Substitutions $irregular)
{
$this->regular = $regular;
$this->uninflected = $uninflected;
$this->irregular = $irregular;
}
public function getRegular() : Transformations
{
return $this->regular;
}
public function getUninflected() : Patterns
{
return $this->uninflected;
}
public function getIrregular() : Substitutions
{
return $this->irregular;
}
}

View File

@ -0,0 +1,43 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Spanish;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitution;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformation;
use RectorPrefix202310\Doctrine\Inflector\Rules\Word;
class Inflectible
{
/** @return Transformation[] */
public static function getSingular() : iterable
{
(yield new Transformation(new Pattern('/ereses$/'), 'erés'));
(yield new Transformation(new Pattern('/iones$/'), 'ión'));
(yield new Transformation(new Pattern('/ces$/'), 'z'));
(yield new Transformation(new Pattern('/es$/'), ''));
(yield new Transformation(new Pattern('/s$/'), ''));
}
/** @return Transformation[] */
public static function getPlural() : iterable
{
(yield new Transformation(new Pattern('/ú([sn])$/i'), 'RectorPrefix202310\\u\\1es'));
(yield new Transformation(new Pattern('/ó([sn])$/i'), 'RectorPrefix202310\\o\\1es'));
(yield new Transformation(new Pattern('/í([sn])$/i'), 'RectorPrefix202310\\i\\1es'));
(yield new Transformation(new Pattern('/é([sn])$/i'), 'RectorPrefix202310\\e\\1es'));
(yield new Transformation(new Pattern('/á([sn])$/i'), 'RectorPrefix202310\\a\\1es'));
(yield new Transformation(new Pattern('/z$/i'), 'ces'));
(yield new Transformation(new Pattern('/([aeiou]s)$/i'), '\\1'));
(yield new Transformation(new Pattern('/([^aeéiou])$/i'), '\\1es'));
(yield new Transformation(new Pattern('/$/'), 's'));
}
/** @return Substitution[] */
public static function getIrregular() : iterable
{
(yield new Substitution(new Word('el'), new Word('los')));
(yield new Substitution(new Word('papá'), new Word('papás')));
(yield new Substitution(new Word('mamá'), new Word('mamás')));
(yield new Substitution(new Word('sofá'), new Word('sofás')));
(yield new Substitution(new Word('mes'), new Word('meses')));
}
}

View File

@ -0,0 +1,18 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Spanish;
use RectorPrefix202310\Doctrine\Inflector\GenericLanguageInflectorFactory;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset() : Ruleset
{
return Rules::getSingularRuleset();
}
protected function getPluralRuleset() : Ruleset
{
return Rules::getPluralRuleset();
}
}

View File

@ -0,0 +1,20 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Spanish;
use RectorPrefix202310\Doctrine\Inflector\Rules\Patterns;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitutions;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformations;
final class Rules
{
public static function getSingularRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getSingular()), new Patterns(...Uninflected::getSingular()), (new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions());
}
public static function getPluralRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()));
}
}

View File

@ -0,0 +1,26 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Spanish;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
final class Uninflected
{
/** @return Pattern[] */
public static function getSingular() : iterable
{
yield from self::getDefault();
}
/** @return Pattern[] */
public static function getPlural() : iterable
{
yield from self::getDefault();
}
/** @return Pattern[] */
private static function getDefault() : iterable
{
(yield new Pattern('lunes'));
(yield new Pattern('rompecabezas'));
(yield new Pattern('crisis'));
}
}

View File

@ -0,0 +1,25 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules;
final class Substitution
{
/** @var Word */
private $from;
/** @var Word */
private $to;
public function __construct(Word $from, Word $to)
{
$this->from = $from;
$this->to = $to;
}
public function getFrom() : Word
{
return $this->from;
}
public function getTo() : Word
{
return $this->to;
}
}

View File

@ -0,0 +1,41 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules;
use RectorPrefix202310\Doctrine\Inflector\WordInflector;
use function strtolower;
use function strtoupper;
use function substr;
class Substitutions implements WordInflector
{
/** @var Substitution[] */
private $substitutions;
public function __construct(Substitution ...$substitutions)
{
foreach ($substitutions as $substitution) {
$this->substitutions[$substitution->getFrom()->getWord()] = $substitution;
}
}
public function getFlippedSubstitutions() : Substitutions
{
$substitutions = [];
foreach ($this->substitutions as $substitution) {
$substitutions[] = new Substitution($substitution->getTo(), $substitution->getFrom());
}
return new Substitutions(...$substitutions);
}
public function inflect(string $word) : string
{
$lowerWord = strtolower($word);
if (isset($this->substitutions[$lowerWord])) {
$firstLetterUppercase = $lowerWord[0] !== $word[0];
$toWord = $this->substitutions[$lowerWord]->getTo()->getWord();
if ($firstLetterUppercase) {
return strtoupper($toWord[0]) . substr($toWord, 1);
}
return $toWord;
}
return $word;
}
}

View File

@ -0,0 +1,31 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules;
use RectorPrefix202310\Doctrine\Inflector\WordInflector;
use function preg_replace;
final class Transformation implements WordInflector
{
/** @var Pattern */
private $pattern;
/** @var string */
private $replacement;
public function __construct(Pattern $pattern, string $replacement)
{
$this->pattern = $pattern;
$this->replacement = $replacement;
}
public function getPattern() : Pattern
{
return $this->pattern;
}
public function getReplacement() : string
{
return $this->replacement;
}
public function inflect(string $word) : string
{
return (string) preg_replace($this->pattern->getRegex(), $this->replacement, $word);
}
}

View File

@ -0,0 +1,24 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules;
use RectorPrefix202310\Doctrine\Inflector\WordInflector;
class Transformations implements WordInflector
{
/** @var Transformation[] */
private $transformations;
public function __construct(Transformation ...$transformations)
{
$this->transformations = $transformations;
}
public function inflect(string $word) : string
{
foreach ($this->transformations as $transformation) {
if ($transformation->getPattern()->matches($word)) {
return $transformation->inflect($word);
}
}
return $word;
}
}

View File

@ -0,0 +1,30 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Turkish;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitution;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformation;
use RectorPrefix202310\Doctrine\Inflector\Rules\Word;
class Inflectible
{
/** @return Transformation[] */
public static function getSingular() : iterable
{
(yield new Transformation(new Pattern('/l[ae]r$/i'), ''));
}
/** @return Transformation[] */
public static function getPlural() : iterable
{
(yield new Transformation(new Pattern('/([eöiü][^aoıueöiü]{0,6})$/u'), '\\1ler'));
(yield new Transformation(new Pattern('/([aoıu][^aoıueöiü]{0,6})$/u'), '\\1lar'));
}
/** @return Substitution[] */
public static function getIrregular() : iterable
{
(yield new Substitution(new Word('ben'), new Word('biz')));
(yield new Substitution(new Word('sen'), new Word('siz')));
(yield new Substitution(new Word('o'), new Word('onlar')));
}
}

View File

@ -0,0 +1,18 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Turkish;
use RectorPrefix202310\Doctrine\Inflector\GenericLanguageInflectorFactory;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset() : Ruleset
{
return Rules::getSingularRuleset();
}
protected function getPluralRuleset() : Ruleset
{
return Rules::getPluralRuleset();
}
}

View File

@ -0,0 +1,20 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Turkish;
use RectorPrefix202310\Doctrine\Inflector\Rules\Patterns;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
use RectorPrefix202310\Doctrine\Inflector\Rules\Substitutions;
use RectorPrefix202310\Doctrine\Inflector\Rules\Transformations;
final class Rules
{
public static function getSingularRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getSingular()), new Patterns(...Uninflected::getSingular()), (new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions());
}
public static function getPluralRuleset() : Ruleset
{
return new Ruleset(new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()));
}
}

View File

@ -0,0 +1,26 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules\Turkish;
use RectorPrefix202310\Doctrine\Inflector\Rules\Pattern;
final class Uninflected
{
/** @return Pattern[] */
public static function getSingular() : iterable
{
yield from self::getDefault();
}
/** @return Pattern[] */
public static function getPlural() : iterable
{
yield from self::getDefault();
}
/** @return Pattern[] */
private static function getDefault() : iterable
{
(yield new Pattern('lunes'));
(yield new Pattern('rompecabezas'));
(yield new Pattern('crisis'));
}
}

View File

@ -0,0 +1,18 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector\Rules;
class Word
{
/** @var string */
private $word;
public function __construct(string $word)
{
$this->word = $word;
}
public function getWord() : string
{
return $this->word;
}
}

View File

@ -0,0 +1,45 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector;
use RectorPrefix202310\Doctrine\Inflector\Rules\Ruleset;
use function array_merge;
/**
* Inflects based on multiple rulesets.
*
* Rules:
* - If the word matches any uninflected word pattern, it is not inflected
* - The first ruleset that returns a different value for an irregular word wins
* - The first ruleset that returns a different value for a regular word wins
* - If none of the above match, the word is left as-is
*/
class RulesetInflector implements WordInflector
{
/** @var Ruleset[] */
private $rulesets;
public function __construct(Ruleset $ruleset, Ruleset ...$rulesets)
{
$this->rulesets = array_merge([$ruleset], $rulesets);
}
public function inflect(string $word) : string
{
if ($word === '') {
return '';
}
foreach ($this->rulesets as $ruleset) {
if ($ruleset->getUninflected()->matches($word)) {
return $word;
}
$inflected = $ruleset->getIrregular()->inflect($word);
if ($inflected !== $word) {
return $inflected;
}
$inflected = $ruleset->getRegular()->inflect($word);
if ($inflected !== $word) {
return $inflected;
}
}
return $word;
}
}

View File

@ -0,0 +1,9 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202310\Doctrine\Inflector;
interface WordInflector
{
public function inflect(string $word) : string;
}