LICENSE000064400000002051144760114510005552 0ustar00Copyright (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. README.md000064400000001146144760114510006030 0ustar00# 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://travis-ci.org/doctrine/inflector.svg)](https://travis-ci.org/doctrine/inflector) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/inflector/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/inflector/?branch=master) [![Code Coverage](https://scrutinizer-ci.com/g/doctrine/inflector/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/inflector/?branch=master) composer.json000064400000003176144760114510007300 0ustar00{ "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": "^7.0", "phpstan/phpstan": "^0.11", "phpstan/phpstan-phpunit": "^0.11", "phpstan/phpstan-strict-rules": "^0.11", "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "autoload": { "psr-4": { "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector", "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" } }, "autoload-dev": { "psr-4": { "Doctrine\\Tests\\Common\\Inflector\\": "tests/Doctrine/Tests/Common/Inflector", "Doctrine\\Tests\\Inflector\\": "tests/Doctrine/Tests/Inflector" } }, "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } } } docs/en/index.rst000064400000014574144760114510007755 0ustar00Introduction ============ 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 `_. .. 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 `_ - `ICanBoogie Inflector `_ - `CakePHP Inflector `_ lib/Doctrine/Common/Inflector/Inflector.php000064400000023033144760114510014700 0ustar00. */ namespace Doctrine\Common\Inflector; use Doctrine\Inflector\Inflector as InflectorObject; use Doctrine\Inflector\InflectorFactory; use Doctrine\Inflector\LanguageInflectorFactory; 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; use InvalidArgumentException; use function array_keys; use function array_map; use function array_unshift; use function array_values; use function sprintf; use function trigger_error; use const E_USER_DEPRECATED; /** * @deprecated */ class Inflector { /** * @var LanguageInflectorFactory|null */ private static $factory; /** @var InflectorObject|null */ private static $instance; private static function getInstance() : InflectorObject { if (self::$factory === null) { self::$factory = self::createFactory(); } if (self::$instance === null) { self::$instance = self::$factory->build(); } return self::$instance; } private static function createFactory() : LanguageInflectorFactory { return InflectorFactory::create(); } /** * Converts a word into the format for a Doctrine table name. Converts 'ModelName' to 'model_name'. * * @deprecated */ public static function tableize(string $word) : string { @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); return self::getInstance()->tableize($word); } /** * Converts a word into the format for a Doctrine class name. Converts 'table_name' to 'TableName'. */ public static function classify(string $word) : string { @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); return self::getInstance()->classify($word); } /** * Camelizes a word. This uses the classify() method and turns the first character to lowercase. * * @deprecated */ public static function camelize(string $word) : string { @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); return self::getInstance()->camelize($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: * * * * * @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. * * @deprecated */ public static function ucwords(string $string, string $delimiters = " \n\t\r\0\x0B-") : string { @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please use the "ucwords" function instead.', __METHOD__), E_USER_DEPRECATED); return ucwords($string, $delimiters); } /** * Clears Inflectors inflected value caches, and resets the inflection * rules to the initial values. * * @deprecated */ public static function reset() : void { @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); self::$factory = null; self::$instance = null; } /** * Adds custom inflection $rules, of either 'plural' or 'singular' $type. * * ### Usage: * * {{{ * Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables')); * Inflector::rules('plural', array( * 'rules' => array('/^(inflect)ors$/i' => '\1ables'), * 'uninflected' => array('dontinflectme'), * 'irregular' => array('red' => 'redlings') * )); * }}} * * @param string $type The type of inflection, either 'plural' or 'singular' * @param array|iterable $rules An array of rules to be added. * @param boolean $reset If true, will unset default inflections for all * new rules that are being defined in $rules. * * @return void * * @deprecated */ public static function rules(string $type, iterable $rules, bool $reset = false) : void { @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); if (self::$factory === null) { self::$factory = self::createFactory(); } self::$instance = null; switch ($type) { case 'singular': self::$factory->withSingularRules(self::buildRuleset($rules), $reset); break; case 'plural': self::$factory->withPluralRules(self::buildRuleset($rules), $reset); break; default: throw new InvalidArgumentException(sprintf('Cannot define custom inflection rules for type "%s".', $type)); } } private static function buildRuleset(iterable $rules) : Ruleset { $regular = []; $irregular = []; $uninflected = []; foreach ($rules as $rule => $pattern) { if ( ! is_array($pattern)) { $regular[$rule] = $pattern; continue; } switch ($rule) { case 'uninflected': $uninflected = $pattern; break; case 'irregular': $irregular = $pattern; break; case 'rules': $regular = $pattern; break; } } return new Ruleset( new Transformations(...array_map( static function (string $pattern, string $replacement) : Transformation { return new Transformation(new Pattern($pattern), $replacement); }, array_keys($regular), array_values($regular) )), new Patterns(...array_map( static function (string $pattern) : Pattern { return new Pattern($pattern); }, $uninflected )), new Substitutions(...array_map( static function (string $word, string $to) : Substitution { return new Substitution(new Word($word), new Word($to)); }, array_keys($irregular), array_values($irregular) )) ); } /** * Returns a word in plural form. * * @param string $word The word in singular form. * * @return string The word in plural form. * * @deprecated */ public static function pluralize(string $word) : string { @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); return self::getInstance()->pluralize($word); } /** * Returns a word in singular form. * * @param string $word The word in plural form. * * @return string The word in singular form. * * @deprecated */ public static function singularize(string $word) : string { @trigger_error(sprintf('The "%s" method is deprecated and will be dropped in doctrine/inflector 2.0. Please update to the new Inflector API.', __METHOD__), E_USER_DEPRECATED); return self::getInstance()->singularize($word); } } lib/Doctrine/Inflector/CachedWordInflector.php000064400000001000144760114510015362 0ustar00wordInflector = $wordInflector; } public function inflect(string $word) : string { return $this->cache[$word] ?? $this->cache[$word] = $this->wordInflector->inflect($word); } } lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php000064400000003217144760114510017743 0ustar00singularRulesets[] = $this->getSingularRuleset(); $this->pluralRulesets[] = $this->getPluralRuleset(); } final public function build() : Inflector { return new Inflector( new CachedWordInflector(new RulesetInflector( ...$this->singularRulesets )), new CachedWordInflector(new RulesetInflector( ...$this->pluralRulesets )) ); } final public function withSingularRules(?Ruleset $singularRules, bool $reset = false) : LanguageInflectorFactory { if ($reset) { $this->singularRulesets = []; } if ($singularRules instanceof Ruleset) { array_unshift($this->singularRulesets, $singularRules); } return $this; } final public function withPluralRules(?Ruleset $pluralRules, bool $reset = false) : LanguageInflectorFactory { if ($reset) { $this->pluralRulesets = []; } if ($pluralRules instanceof Ruleset) { array_unshift($this->pluralRulesets, $pluralRules); } return $this; } abstract protected function getSingularRuleset() : Ruleset; abstract protected function getPluralRuleset() : Ruleset; } lib/Doctrine/Inflector/Inflector.php000064400000031070144760114510013450 0ustar00 '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: * * capitalize($string); * // Top-O-The-Morning To All_of_you! * * echo $inflector->capitalize($string, '-_ '); * // Top-O-The-Morning To All_Of_You! * ?> * * * @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\0\x0B-") : 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])/' => '\1_\2', '/([a-z\d])([A-Z])/' => '\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); } } lib/Doctrine/Inflector/InflectorFactory.php000064400000002611144760114510014777 0ustar00getFlippedSubstitutions() ); } public static function getPluralRuleset() : Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } lib/Doctrine/Inflector/Rules/English/Uninflected.php000064400000014557144760114510016461 0ustar00getFlippedSubstitutions() ); } public static function getPluralRuleset() : Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } lib/Doctrine/Inflector/Rules/French/Uninflected.php000064400000001070144760114510016257 0ustar00getFlippedSubstitutions() ); } public static function getPluralRuleset() : Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } lib/Doctrine/Inflector/Rules/NorwegianBokmal/Uninflected.php000064400000001213144760114510020130 0ustar00pattern = $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; } } lib/Doctrine/Inflector/Rules/Patterns.php000064400000001272144760114510014416 0ustar00patterns = $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; } } lib/Doctrine/Inflector/Rules/Portuguese/Inflectible.php000064400000013067144760114510017205 0ustar00getFlippedSubstitutions() ); } public static function getPluralRuleset() : Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } lib/Doctrine/Inflector/Rules/Portuguese/Uninflected.php000064400000001327144760114510017221 0ustar00regular = $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; } } lib/Doctrine/Inflector/Rules/Spanish/Inflectible.php000064400000003540144760114510016443 0ustar00getFlippedSubstitutions() ); } public static function getPluralRuleset() : Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } lib/Doctrine/Inflector/Rules/Spanish/Uninflected.php000064400000001216144760114510016461 0ustar00from = $from; $this->to = $to; } public function getFrom() : Word { return $this->from; } public function getTo() : Word { return $this->to; } } lib/Doctrine/Inflector/Rules/Substitutions.php000064400000002535144760114510015520 0ustar00substitutions[$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; } } lib/Doctrine/Inflector/Rules/Transformation.php000064400000001430144760114510015620 0ustar00pattern = $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); } } lib/Doctrine/Inflector/Rules/Transformations.php000064400000001211144760114510016000 0ustar00transformations = $transformations; } public function inflect(string $word) : string { foreach ($this->transformations as $transformation) { if ($transformation->getPattern()->matches($word)) { return $transformation->inflect($word); } } return $word; } } lib/Doctrine/Inflector/Rules/Turkish/Inflectible.php000064400000002025144760114510016464 0ustar00getFlippedSubstitutions() ); } public static function getPluralRuleset() : Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } lib/Doctrine/Inflector/Rules/Turkish/Uninflected.php000064400000001216144760114510016505 0ustar00word = $word; } public function getWord() : string { return $this->word; } } lib/Doctrine/Inflector/RulesetInflector.php000064400000002513144760114510015014 0ustar00rulesets = 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; } } lib/Doctrine/Inflector/WordInflector.php000064400000000220144760114510014275 0ustar00