diff --git a/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php b/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php index 166061d..b6a9325 100644 --- a/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php +++ b/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php @@ -4,9 +4,15 @@ namespace Doctrine\Inflector; +use Doctrine\Inflector\Rules\Patterns; use Doctrine\Inflector\Rules\Ruleset; +use Doctrine\Inflector\Rules\Substitution; +use Doctrine\Inflector\Rules\Substitutions; +use Doctrine\Inflector\Rules\Transformations; +use Doctrine\Inflector\Rules\Word; use function array_unshift; +use function is_array; abstract class GenericLanguageInflectorFactory implements LanguageInflectorFactory { @@ -60,6 +66,33 @@ final public function withPluralRules(?Ruleset $pluralRules, bool $reset = false return $this; } + final public function withIrregulars(?array $irregulars, bool $reset = false): LanguageInflectorFactory + { + if ($reset) { + $this->pluralRulesets = []; + $this->singularRulesets = []; + } + + if (is_array($irregulars)) { + $newIrregulars = []; + foreach ($irregulars as $irregular) { + $newIrregulars[] = new Substitution(new Word($irregular[0]), new Word($irregular[1])); + } + + $transf = new Transformations(); + $patterns = new Patterns(); + $substs = new Substitutions(...$newIrregulars); + + $plural = new Ruleset($transf, $patterns, $substs); + $singular = new Ruleset($transf, $patterns, $substs->getFlippedSubstitutions()); + + array_unshift($this->pluralRulesets, $plural); + array_unshift($this->singularRulesets, $singular); + } + + return $this; + } + abstract protected function getSingularRuleset(): Ruleset; abstract protected function getPluralRuleset(): Ruleset; diff --git a/lib/Doctrine/Inflector/LanguageInflectorFactory.php b/lib/Doctrine/Inflector/LanguageInflectorFactory.php index a58f43c..6d9d924 100644 --- a/lib/Doctrine/Inflector/LanguageInflectorFactory.php +++ b/lib/Doctrine/Inflector/LanguageInflectorFactory.php @@ -26,6 +26,16 @@ public function withSingularRules(?Ruleset $singularRules, bool $reset = false): */ public function withPluralRules(?Ruleset $pluralRules, bool $reset = false): self; + /** + * Applies custom rules for irregular words + * + * @param mixed[][] $irregulars Array of arrays of strings in the format [['singular', 'plural'], ...] + * @param bool $reset If true, will unset default inflections for all new rules + * + * @return $this + */ + public function withIrregulars(?array $irregulars, bool $reset = false): self; + /** * Builds the inflector instance with all applicable rules */ diff --git a/tests/Doctrine/Tests/Inflector/InflectorWithIrregularsTest.php b/tests/Doctrine/Tests/Inflector/InflectorWithIrregularsTest.php new file mode 100644 index 0000000..da60476 --- /dev/null +++ b/tests/Doctrine/Tests/Inflector/InflectorWithIrregularsTest.php @@ -0,0 +1,69 @@ +inflector->pluralize($word)); + self::assertSame($word, $this->inflector->singularize($expected)); + } + + /** + * @dataProvider dataRegulars + */ + public function testRegulars(string $word, string $expected): void + { + self::assertSame($expected, $this->inflector->pluralize($word)); + self::assertSame($word, $this->inflector->singularize($expected)); + } + + /** + * Strings which are used for testTableize. + * + * @return string[][] + */ + public function dataRegulars(): array + { + // In the format array('word', 'expected') + return [ + ['address', 'addresses'], + ['advice', 'advice'], + ['agency', 'agencies'], + ['aircraft', 'aircraft'], + ['alias', 'aliases'], + ]; + } + + /** + * Strings which are used for testIrregulars. + * + * @return string[][] + */ + public function dataIrregulars(): array + { + // In the format array('word', 'expected') + return [ + ['foobar', 'barfoo'], + ['test', 'testz'], + ]; + } + + protected function setUp(): void + { + $this->inflector = InflectorFactory::create()->withIrregulars($this->dataIrregulars())->build(); + } +}