PKn Zne2deprecations/phpcs.xmlnu[ lib tests PKn Z.͚deprecations/composer.jsonnu[{ "name": "doctrine/deprecations", "type": "library", "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", "homepage": "https://www.doctrine-project.org/", "license": "MIT", "require": { "php": "^7.1|^8.0" }, "require-dev": { "phpunit/phpunit": "^7.5|^8.5|^9.5", "psr/log": "^1|^2|^3", "doctrine/coding-standard": "^9" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" }, "autoload": { "psr-4": {"Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"} }, "autoload-dev": { "psr-4": { "DeprecationTests\\": "test_fixtures/src", "Doctrine\\Foo\\": "test_fixtures/vendor/doctrine/foo" } }, "config": { "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true } } } PKn Z */ private static $ignoredPackages = []; /** @var array */ private static $ignoredLinks = []; /** @var bool */ private static $deduplication = true; /** * Trigger a deprecation for the given package and identfier. * * The link should point to a Github issue or Wiki entry detailing the * deprecation. It is additionally used to de-duplicate the trigger of the * same deprecation during a request. * * @param mixed $args */ public static function trigger(string $package, string $link, string $message, ...$args): void { if (self::$type === self::TYPE_NONE) { return; } if (array_key_exists($link, self::$ignoredLinks)) { self::$ignoredLinks[$link]++; } else { self::$ignoredLinks[$link] = 1; } if (self::$deduplication === true && self::$ignoredLinks[$link] > 1) { return; } if (isset(self::$ignoredPackages[$package])) { return; } $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); $message = sprintf($message, ...$args); self::delegateTriggerToBackend($message, $backtrace, $link, $package); } /** * Trigger a deprecation for the given package and identifier when called from outside. * * "Outside" means we assume that $package is currently installed as a * dependency and the caller is not a file in that package. When $package * is installed as a root package then deprecations triggered from the * tests folder are also considered "outside". * * This deprecation method assumes that you are using Composer to install * the dependency and are using the default /vendor/ folder and not a * Composer plugin to change the install location. The assumption is also * that $package is the exact composer packge name. * * Compared to {@link trigger()} this method causes some overhead when * deprecation tracking is enabled even during deduplication, because it * needs to call {@link debug_backtrace()} * * @param mixed $args */ public static function triggerIfCalledFromOutside(string $package, string $link, string $message, ...$args): void { if (self::$type === self::TYPE_NONE) { return; } $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); // first check that the caller is not from a tests folder, in which case we always let deprecations pass if (strpos($backtrace[1]['file'], DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR) === false) { $path = DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package . DIRECTORY_SEPARATOR; if (strpos($backtrace[0]['file'], $path) === false) { return; } if (strpos($backtrace[1]['file'], $path) !== false) { return; } } if (array_key_exists($link, self::$ignoredLinks)) { self::$ignoredLinks[$link]++; } else { self::$ignoredLinks[$link] = 1; } if (self::$deduplication === true && self::$ignoredLinks[$link] > 1) { return; } if (isset(self::$ignoredPackages[$package])) { return; } $message = sprintf($message, ...$args); self::delegateTriggerToBackend($message, $backtrace, $link, $package); } /** * @param array $backtrace */ private static function delegateTriggerToBackend(string $message, array $backtrace, string $link, string $package): void { if ((self::$type & self::TYPE_PSR_LOGGER) > 0) { $context = [ 'file' => $backtrace[0]['file'], 'line' => $backtrace[0]['line'], 'package' => $package, 'link' => $link, ]; self::$logger->notice($message, $context); } if (! ((self::$type & self::TYPE_TRIGGER_ERROR) > 0)) { return; } $message .= sprintf( ' (%s:%d called by %s:%d, %s, package %s)', self::basename($backtrace[0]['file']), $backtrace[0]['line'], self::basename($backtrace[1]['file']), $backtrace[1]['line'], $link, $package ); @trigger_error($message, E_USER_DEPRECATED); } /** * A non-local-aware version of PHPs basename function. */ private static function basename(string $filename): string { $pos = strrpos($filename, DIRECTORY_SEPARATOR); if ($pos === false) { return $filename; } return substr($filename, $pos + 1); } public static function enableTrackingDeprecations(): void { self::$type |= self::TYPE_TRACK_DEPRECATIONS; } public static function enableWithTriggerError(): void { self::$type |= self::TYPE_TRIGGER_ERROR; } public static function enableWithPsrLogger(LoggerInterface $logger): void { self::$type |= self::TYPE_PSR_LOGGER; self::$logger = $logger; } public static function withoutDeduplication(): void { self::$deduplication = false; } public static function disable(): void { self::$type = self::TYPE_NONE; self::$logger = null; self::$deduplication = true; foreach (self::$ignoredLinks as $link => $count) { self::$ignoredLinks[$link] = 0; } } public static function ignorePackage(string $packageName): void { self::$ignoredPackages[$packageName] = true; } public static function ignoreDeprecations(string ...$links): void { foreach ($links as $link) { self::$ignoredLinks[$link] = 0; } } public static function getUniqueTriggeredDeprecationsCount(): int { return array_reduce(self::$ignoredLinks, static function (int $carry, int $count) { return $carry + $count; }, 0); } /** * Returns each triggered deprecation link identifier and the amount of occurrences. * * @return array */ public static function getTriggeredDeprecations(): array { return self::$ignoredLinks; } } PKn Z/GdzEdeprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.phpnu[ */ private $doctrineDeprecationsExpectations = []; /** @var array */ private $doctrineNoDeprecationsExpectations = []; public function expectDeprecationWithIdentifier(string $identifier): void { $this->doctrineDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; } public function expectNoDeprecationWithIdentifier(string $identifier): void { $this->doctrineNoDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; } /** * @before */ public function enableDeprecationTracking(): void { Deprecation::enableTrackingDeprecations(); } /** * @after */ public function verifyDeprecationsAreTriggered(): void { foreach ($this->doctrineDeprecationsExpectations as $identifier => $expectation) { $actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; $this->assertTrue( $actualCount > $expectation, sprintf( "Expected deprecation with identifier '%s' was not triggered by code executed in test.", $identifier ) ); } foreach ($this->doctrineNoDeprecationsExpectations as $identifier => $expectation) { $actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; $this->assertTrue( $actualCount === $expectation, sprintf( "Expected deprecation with identifier '%s' was triggered by code executed in test, but expected not to.", $identifier ) ); } } } PKn Z0Fvvvdeprecations/README.mdnu[# Doctrine Deprecations A small (side-effect free by default) layer on top of `trigger_error(E_USER_DEPRECATED)` or PSR-3 logging. - no side-effects by default, making it a perfect fit for libraries that don't know how the error handler works they operate under - options to avoid having to rely on error handlers global state by using PSR-3 logging - deduplicate deprecation messages to avoid excessive triggering and reduce overhead We recommend to collect Deprecations using a PSR logger instead of relying on the global error handler. ## Usage from consumer perspective: Enable Doctrine deprecations to be sent to a PSR3 logger: ```php \Doctrine\Deprecations\Deprecation::enableWithPsrLogger($logger); ``` Enable Doctrine deprecations to be sent as `@trigger_error($message, E_USER_DEPRECATED)` messages. ```php \Doctrine\Deprecations\Deprecation::enableWithTriggerError(); ``` If you only want to enable deprecation tracking, without logging or calling `trigger_error` then call: ```php \Doctrine\Deprecations\Deprecation::enableTrackingDeprecations(); ``` Tracking is enabled with all three modes and provides access to all triggered deprecations and their individual count: ```php $deprecations = \Doctrine\Deprecations\Deprecation::getTriggeredDeprecations(); foreach ($deprecations as $identifier => $count) { echo $identifier . " was triggered " . $count . " times\n"; } ``` ### Suppressing Specific Deprecations Disable triggering about specific deprecations: ```php \Doctrine\Deprecations\Deprecation::ignoreDeprecations("https://link/to/deprecations-description-identifier"); ``` Disable all deprecations from a package ```php \Doctrine\Deprecations\Deprecation::ignorePackage("doctrine/orm"); ``` ### Other Operations When used within PHPUnit or other tools that could collect multiple instances of the same deprecations the deduplication can be disabled: ```php \Doctrine\Deprecations\Deprecation::withoutDeduplication(); ``` Disable deprecation tracking again: ```php \Doctrine\Deprecations\Deprecation::disable(); ``` ## Usage from a library/producer perspective: When you want to unconditionally trigger a deprecation even when called from the library itself then the `trigger` method is the way to go: ```php \Doctrine\Deprecations\Deprecation::trigger( "doctrine/orm", "https://link/to/deprecations-description", "message" ); ``` If variable arguments are provided at the end, they are used with `sprintf` on the message. ```php \Doctrine\Deprecations\Deprecation::trigger( "doctrine/orm", "https://github.com/doctrine/orm/issue/1234", "message %s %d", "foo", 1234 ); ``` When you want to trigger a deprecation only when it is called by a function outside of the current package, but not trigger when the package itself is the cause, then use: ```php \Doctrine\Deprecations\Deprecation::triggerIfCalledFromOutside( "doctrine/orm", "https://link/to/deprecations-description", "message" ); ``` Based on the issue link each deprecation message is only triggered once per request. A limited stacktrace is included in the deprecation message to find the offending location. Note: A producer/library should never call `Deprecation::enableWith` methods and leave the decision how to handle deprecations to application and frameworks. ## Usage in PHPUnit tests There is a `VerifyDeprecations` trait that you can use to make assertions on the occurrence of deprecations within a test. ```php use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; class MyTest extends TestCase { use VerifyDeprecations; public function testSomethingDeprecation() { $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/issue/1234'); triggerTheCodeWithDeprecation(); } public function testSomethingDeprecationFixed() { $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issue/1234'); triggerTheCodeWithoutDeprecation(); } } ``` ## What is a deprecation identifier? An identifier for deprecations is just a link to any resource, most often a Github Issue or Pull Request explaining the deprecation and potentially its alternative. PKn Z"0))deprecations/LICENSEnu[Copyright (c) 2020-2021 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. PKn Zچinflector/composer.jsonnu[{ "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": "^10", "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" }, "autoload": { "psr-4": { "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" } }, "autoload-dev": { "psr-4": { "Doctrine\\Tests\\Inflector\\": "tests/Doctrine/Tests/Inflector" } }, "config": { "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true } } } PKn Z##l2inflector/lib/Doctrine/Inflector/WordInflector.phpnu[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; } } PKn Z0202.inflector/lib/Doctrine/Inflector/Inflector.phpnu[ '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); } } PKn Z3Finflector/lib/Doctrine/Inflector/Rules/Portuguese/InflectorFactory.phpnu[getFlippedSubstitutions() ); } public static function getPluralRuleset(): Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } PKn Z@YoAinflector/lib/Doctrine/Inflector/Rules/Portuguese/Inflectible.phpnu[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); } } PKn Za_2inflector/lib/Doctrine/Inflector/Rules/Pattern.phpnu[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; } } PKn Z[Cinflector/lib/Doctrine/Inflector/Rules/Spanish/InflectorFactory.phpnu[inflector/lib/Doctrine/Inflector/Rules/Spanish/Uninflected.phpnu[getFlippedSubstitutions() ); } public static function getPluralRuleset(): Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } PKn Z͕99>inflector/lib/Doctrine/Inflector/Rules/Spanish/Inflectible.phpnu[getFlippedSubstitutions() ); } public static function getPluralRuleset(): Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } PKn Z{<Finflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Inflectible.phpnu[from = $from; $this->to = $to; } public function getFrom(): Word { return $this->from; } public function getTo(): Word { return $this->to; } } PKn ZY?Cinflector/lib/Doctrine/Inflector/Rules/English/InflectorFactory.phpnu[inflector/lib/Doctrine/Inflector/Rules/English/Uninflected.phpnu[getFlippedSubstitutions() ); } public static function getPluralRuleset(): Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } PKn Z. 8-8->inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.phpnu[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; } } PKn Z~2Binflector/lib/Doctrine/Inflector/Rules/French/InflectorFactory.phpnu[getFlippedSubstitutions() ); } public static function getPluralRuleset(): Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } PKn ZyXVV=inflector/lib/Doctrine/Inflector/Rules/French/Inflectible.phpnu[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; } } PKn ZKHW&&/inflector/lib/Doctrine/Inflector/Rules/Word.phpnu[word = $word; } public function getWord(): string { return $this->word; } } PKn Z Cinflector/lib/Doctrine/Inflector/Rules/Turkish/InflectorFactory.phpnu[Yεgg>inflector/lib/Doctrine/Inflector/Rules/Turkish/Uninflected.phpnu[getFlippedSubstitutions() ); } public static function getPluralRuleset(): Ruleset { return new Ruleset( new Transformations(...Inflectible::getPlural()), new Patterns(...Uninflected::getPlural()), new Substitutions(...Inflectible::getIrregular()) ); } } PKn ZJ>inflector/lib/Doctrine/Inflector/Rules/Turkish/Inflectible.phpnu[transformations = $transformations; } public function inflect(string $word): string { foreach ($this->transformations as $transformation) { if ($transformation->getPattern()->matches($word)) { return $transformation->inflect($word); } } return $word; } } PKn ZfP  2inflector/lib/Doctrine/Inflector/Rules/Ruleset.phpnu[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; } } PKn Z[_i8inflector/lib/Doctrine/Inflector/CachedWordInflector.phpnu[wordInflector = $wordInflector; } public function inflect(string $word): string { return $this->cache[$word] ?? $this->cache[$word] = $this->wordInflector->inflect($word); } } PKn Z;Dinflector/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.phpnu[singularRulesets[] = $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; } PKn Z]9@q5inflector/lib/Doctrine/Inflector/InflectorFactory.phpnu[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 `_ PKn Zinstantiator/composer.jsonnu[{ "name": "doctrine/instantiator", "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", "type": "library", "license": "MIT", "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "instantiate", "constructor" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", "homepage": "https://ocramius.github.io/" } ], "require": { "php": "^7.1 || ^8.0" }, "require-dev": { "ext-phar": "*", "ext-pdo": "*", "doctrine/coding-standard": "^9 || ^11", "phpbench/phpbench": "^0.16 || ^1", "phpstan/phpstan": "^1.4", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "vimeo/psalm": "^4.30 || ^5.4" }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "autoload-dev": { "psr-0": { "DoctrineTest\\InstantiatorPerformance\\": "tests", "DoctrineTest\\InstantiatorTest\\": "tests", "DoctrineTest\\InstantiatorTestAsset\\": "tests" } }, "config": { "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true } } } PKn Zz.WWMinstantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.phpnu[ $reflectionClass * * @template T of object */ public static function fromSerializationTriggeredException( ReflectionClass $reflectionClass, Exception $exception ): self { return new self( sprintf( 'An exception was raised while trying to instantiate an instance of "%s" via un-serialization', $reflectionClass->getName() ), 0, $exception ); } /** * @phpstan-param ReflectionClass $reflectionClass * * @template T of object */ public static function fromUncleanUnSerialization( ReflectionClass $reflectionClass, string $errorString, int $errorCode, string $errorFile, int $errorLine ): self { return new self( sprintf( 'Could not produce an instance of "%s" via un-serialization, since an error was triggered ' . 'in file "%s" at line "%d"', $reflectionClass->getName(), $errorFile, $errorLine ), 0, new Exception($errorString, $errorCode) ); } } PKn Z$8Minstantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.phpnu[ $reflectionClass * * @template T of object */ public static function fromAbstractClass(ReflectionClass $reflectionClass): self { return new self(sprintf( 'The provided class "%s" is abstract, and cannot be instantiated', $reflectionClass->getName() )); } public static function fromEnum(string $className): self { return new self(sprintf( 'The provided class "%s" is an enum, and cannot be instantiated', $className )); } } PKn ZfGinstantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.phpnu[ $className * * @return object * @phpstan-return T * * @throws ExceptionInterface * * @template T of object */ public function instantiate($className) { if (isset(self::$cachedCloneables[$className])) { /** @phpstan-var T */ $cachedCloneable = self::$cachedCloneables[$className]; return clone $cachedCloneable; } if (isset(self::$cachedInstantiators[$className])) { $factory = self::$cachedInstantiators[$className]; return $factory(); } return $this->buildAndCacheFromFactory($className); } /** * Builds the requested object and caches it in static properties for performance * * @phpstan-param class-string $className * * @return object * @phpstan-return T * * @template T of object */ private function buildAndCacheFromFactory(string $className) { $factory = self::$cachedInstantiators[$className] = $this->buildFactory($className); $instance = $factory(); if ($this->isSafeToClone(new ReflectionClass($instance))) { self::$cachedCloneables[$className] = clone $instance; } return $instance; } /** * Builds a callable capable of instantiating the given $className without * invoking its constructor. * * @phpstan-param class-string $className * * @phpstan-return callable(): T * * @throws InvalidArgumentException * @throws UnexpectedValueException * @throws ReflectionException * * @template T of object */ private function buildFactory(string $className): callable { $reflectionClass = $this->getReflectionClass($className); if ($this->isInstantiableViaReflection($reflectionClass)) { return [$reflectionClass, 'newInstanceWithoutConstructor']; } $serializedString = sprintf( '%s:%d:"%s":0:{}', is_subclass_of($className, Serializable::class) ? self::SERIALIZATION_FORMAT_USE_UNSERIALIZER : self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER, strlen($className), $className ); $this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString); return static function () use ($serializedString) { return unserialize($serializedString); }; } /** * @phpstan-param class-string $className * * @phpstan-return ReflectionClass * * @throws InvalidArgumentException * @throws ReflectionException * * @template T of object */ private function getReflectionClass(string $className): ReflectionClass { if (! class_exists($className)) { throw InvalidArgumentException::fromNonExistingClass($className); } if (PHP_VERSION_ID >= 80100 && enum_exists($className, false)) { throw InvalidArgumentException::fromEnum($className); } $reflection = new ReflectionClass($className); if ($reflection->isAbstract()) { throw InvalidArgumentException::fromAbstractClass($reflection); } return $reflection; } /** * @phpstan-param ReflectionClass $reflectionClass * * @throws UnexpectedValueException * * @template T of object */ private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, string $serializedString): void { set_error_handler(static function (int $code, string $message, string $file, int $line) use ($reflectionClass, &$error): bool { $error = UnexpectedValueException::fromUncleanUnSerialization( $reflectionClass, $message, $code, $file, $line ); return true; }); try { $this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString); } finally { restore_error_handler(); } if ($error) { throw $error; } } /** * @phpstan-param ReflectionClass $reflectionClass * * @throws UnexpectedValueException * * @template T of object */ private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, string $serializedString): void { try { unserialize($serializedString); } catch (Exception $exception) { throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception); } } /** * @phpstan-param ReflectionClass $reflectionClass * * @template T of object */ private function isInstantiableViaReflection(ReflectionClass $reflectionClass): bool { return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal()); } /** * Verifies whether the given class is to be considered internal * * @phpstan-param ReflectionClass $reflectionClass * * @template T of object */ private function hasInternalAncestors(ReflectionClass $reflectionClass): bool { do { if ($reflectionClass->isInternal()) { return true; } $reflectionClass = $reflectionClass->getParentClass(); } while ($reflectionClass); return false; } /** * Checks if a class is cloneable * * Classes implementing `__clone` cannot be safely cloned, as that may cause side-effects. * * @phpstan-param ReflectionClass $reflectionClass * * @template T of object */ private function isSafeToClone(ReflectionClass $reflectionClass): bool { return $reflectionClass->isCloneable() && ! $reflectionClass->hasMethod('__clone') && ! $reflectionClass->isSubclassOf(ArrayIterator::class); } } PKn Z.U@instantiator/src/Doctrine/Instantiator/InstantiatorInterface.phpnu[ $className * * @return object * @phpstan-return T * * @throws ExceptionInterface * * @template T of object */ public function instantiate($className); } PKn Zxxd#instantiator/.doctrine-project.jsonnu[{ "active": true, "name": "Instantiator", "slug": "instantiator", "docsSlug": "doctrine-instantiator", "codePath": "/src", "versions": [ { "name": "1.5", "branchName": "1.5.x", "slug": "latest", "upcoming": true }, { "name": "1.4", "branchName": "1.4.x", "slug": "1.4", "aliases": [ "current", "stable" ], "maintained": true, "current": true }, { "name": "1.3", "branchName": "1.3.x", "slug": "1.3", "maintained": false }, { "name": "1.2", "branchName": "1.2.x", "slug": "1.2" }, { "name": "1.1", "branchName": "1.1.x", "slug": "1.1" }, { "name": "1.0", "branchName": "1.0.x", "slug": "1.0" } ] } PKn Z4@++instantiator/README.mdnu[# Instantiator This library provides a way of avoiding usage of constructors when instantiating PHP classes. [![Build Status](https://travis-ci.org/doctrine/instantiator.svg?branch=master)](https://travis-ci.org/doctrine/instantiator) [![Code Coverage](https://codecov.io/gh/doctrine/instantiator/branch/master/graph/badge.svg)](https://codecov.io/gh/doctrine/instantiator/branch/master) [![Dependency Status](https://www.versioneye.com/package/php--doctrine--instantiator/badge.svg)](https://www.versioneye.com/package/php--doctrine--instantiator) [![Latest Stable Version](https://poser.pugx.org/doctrine/instantiator/v/stable.png)](https://packagist.org/packages/doctrine/instantiator) [![Latest Unstable Version](https://poser.pugx.org/doctrine/instantiator/v/unstable.png)](https://packagist.org/packages/doctrine/instantiator) ## Installation The suggested installation method is via [composer](https://getcomposer.org/): ```sh composer require doctrine/instantiator ``` ## Usage The instantiator is able to create new instances of any class without using the constructor or any API of the class itself: ```php $instantiator = new \Doctrine\Instantiator\Instantiator(); $instance = $instantiator->instantiate(\My\ClassName\Here::class); ``` ## Contributing Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out! ## Credits This library was migrated from [ocramius/instantiator](https://github.com/Ocramius/Instantiator), which has been donated to the doctrine organization, and which is now deprecated in favour of this package. PKn Z ͂$$instantiator/LICENSEnu[Copyright (c) 2014 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. PKn Zv&& instantiator/docs/en/sidebar.rstnu[.. toctree:: :depth: 3 index PKn ZHXinstantiator/docs/en/index.rstnu[Introduction ============ This library provides a way of avoiding usage of constructors when instantiating PHP classes. Installation ============ The suggested installation method is via `composer`_: .. code-block:: console $ composer require doctrine/instantiator Usage ===== The instantiator is able to create new instances of any class without using the constructor or any API of the class itself: .. code-block:: php instantiate(User::class); Contributing ============ - Follow the `Doctrine Coding Standard`_ - The project will follow strict `object calisthenics`_ - Any contribution must provide tests for additional introduced conditions - Any un-confirmed issue needs a failing test case before being accepted - Pull requests must be sent from a new hotfix/feature branch, not from ``master``. Testing ======= The PHPUnit version to be used is the one installed as a dev- dependency via composer: .. code-block:: console $ ./vendor/bin/phpunit Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement won’t be merged. Credits ======= This library was migrated from `ocramius/instantiator`_, which has been donated to the doctrine organization, and which is now deprecated in favour of this package. .. _composer: https://getcomposer.org/ .. _CONTRIBUTING.md: CONTRIBUTING.md .. _ocramius/instantiator: https://github.com/Ocramius/Instantiator .. _Doctrine Coding Standard: https://github.com/doctrine/coding-standard .. _object calisthenics: http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php PKn Zwinstantiator/psalm.xmlnu[ PKn Zﻦinstantiator/CONTRIBUTING.mdnu[# Contributing * Follow the [Doctrine Coding Standard](https://github.com/doctrine/coding-standard) * The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php) * Any contribution must provide tests for additional introduced conditions * Any un-confirmed issue needs a failing test case before being accepted * Pull requests must be sent from a new hotfix/feature branch, not from `master`. ## Installation To install the project and run the tests, you need to clone it first: ```sh $ git clone git://github.com/doctrine/instantiator.git ``` You will then need to run a composer installation: ```sh $ cd Instantiator $ curl -s https://getcomposer.org/installer | php $ php composer.phar update ``` ## Testing The PHPUnit version to be used is the one installed as a dev- dependency via composer: ```sh $ ./vendor/bin/phpunit ``` Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement won't be merged. PKn Zhlexer/composer.jsonnu[{ "name": "doctrine/lexer", "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", "license": "MIT", "type": "library", "keywords": [ "php", "parser", "lexer", "annotations", "docblock" ], "authors": [ { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, { "name": "Roman Borschel", "email": "roman@code-factory.org" }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], "homepage": "https://www.doctrine-project.org/projects/lexer.html", "require": { "php": "^7.1 || ^8.0", "doctrine/deprecations": "^1.0" }, "require-dev": { "doctrine/coding-standard": "^9 || ^10", "phpstan/phpstan": "^1.3", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "psalm/plugin-phpunit": "^0.18.3", "vimeo/psalm": "^4.11 || ^5.0" }, "autoload": { "psr-4": { "Doctrine\\Common\\Lexer\\": "src" } }, "autoload-dev": { "psr-4": { "Doctrine\\Tests\\Common\\Lexer\\": "tests" } }, "config": { "allow-plugins": { "composer/package-versions-deprecated": true, "dealerdirect/phpcodesniffer-composer-installer": true }, "sort-packages": true } } PKn Z+{ lexer/src/Token.phpnu[ */ final class Token implements ArrayAccess { /** * The string value of the token in the input string * * @readonly * @var V */ public $value; /** * The type of the token (identifier, numeric, string, input parameter, none) * * @readonly * @var T|null */ public $type; /** * The position of the token in the input string * * @readonly * @var int */ public $position; /** * @param V $value * @param T|null $type */ public function __construct($value, $type, int $position) { $this->value = $value; $this->type = $type; $this->position = $position; } /** @param T ...$types */ public function isA(...$types): bool { return in_array($this->type, $types, true); } /** * @deprecated Use the value, type or position property instead * {@inheritDoc} */ public function offsetExists($offset): bool { Deprecation::trigger( 'doctrine/lexer', 'https://github.com/doctrine/lexer/pull/79', 'Accessing %s properties via ArrayAccess is deprecated, use the value, type or position property instead', self::class ); return in_array($offset, ['value', 'type', 'position'], true); } /** * @deprecated Use the value, type or position property instead * {@inheritDoc} * * @param O $offset * * @return mixed * @psalm-return ( * O is 'value' * ? V * : ( * O is 'type' * ? T|null * : ( * O is 'position' * ? int * : mixed * ) * ) * ) * * @template O of array-key */ #[ReturnTypeWillChange] public function offsetGet($offset) { Deprecation::trigger( 'doctrine/lexer', 'https://github.com/doctrine/lexer/pull/79', 'Accessing %s properties via ArrayAccess is deprecated, use the value, type or position property instead', self::class ); return $this->$offset; } /** * @deprecated no replacement planned * {@inheritDoc} */ public function offsetSet($offset, $value): void { Deprecation::trigger( 'doctrine/lexer', 'https://github.com/doctrine/lexer/pull/79', 'Setting %s properties via ArrayAccess is deprecated', self::class ); $this->$offset = $value; } /** * @deprecated no replacement planned * {@inheritDoc} */ public function offsetUnset($offset): void { Deprecation::trigger( 'doctrine/lexer', 'https://github.com/doctrine/lexer/pull/79', 'Setting %s properties via ArrayAccess is deprecated', self::class ); $this->$offset = null; } } PKn Z0lexer/src/AbstractLexer.phpnu[> */ private $tokens = []; /** * Current lexer position in input string. * * @var int */ private $position = 0; /** * Current peek of current lexer position. * * @var int */ private $peek = 0; /** * The next token in the input. * * @var mixed[]|null * @psalm-var Token|null */ public $lookahead; /** * The last matched/seen token. * * @var mixed[]|null * @psalm-var Token|null */ public $token; /** * Composed regex for input parsing. * * @var string|null */ private $regex; /** * Sets the input data to be tokenized. * * The Lexer is immediately reset and the new input tokenized. * Any unprocessed tokens from any previous input are lost. * * @param string $input The input to be tokenized. * * @return void */ public function setInput($input) { $this->input = $input; $this->tokens = []; $this->reset(); $this->scan($input); } /** * Resets the lexer. * * @return void */ public function reset() { $this->lookahead = null; $this->token = null; $this->peek = 0; $this->position = 0; } /** * Resets the peek pointer to 0. * * @return void */ public function resetPeek() { $this->peek = 0; } /** * Resets the lexer position on the input to the given position. * * @param int $position Position to place the lexical scanner. * * @return void */ public function resetPosition($position = 0) { $this->position = $position; } /** * Retrieve the original lexer's input until a given position. * * @param int $position * * @return string */ public function getInputUntilPosition($position) { return substr($this->input, 0, $position); } /** * Checks whether a given token matches the current lookahead. * * @param T $type * * @return bool * * @psalm-assert-if-true !=null $this->lookahead */ public function isNextToken($type) { return $this->lookahead !== null && $this->lookahead->isA($type); } /** * Checks whether any of the given tokens matches the current lookahead. * * @param list $types * * @return bool * * @psalm-assert-if-true !=null $this->lookahead */ public function isNextTokenAny(array $types) { return $this->lookahead !== null && $this->lookahead->isA(...$types); } /** * Moves to the next token in the input string. * * @return bool * * @psalm-assert-if-true !null $this->lookahead */ public function moveNext() { $this->peek = 0; $this->token = $this->lookahead; $this->lookahead = isset($this->tokens[$this->position]) ? $this->tokens[$this->position++] : null; return $this->lookahead !== null; } /** * Tells the lexer to skip input tokens until it sees a token with the given value. * * @param T $type The token type to skip until. * * @return void */ public function skipUntil($type) { while ($this->lookahead !== null && ! $this->lookahead->isA($type)) { $this->moveNext(); } } /** * Checks if given value is identical to the given token. * * @param string $value * @param int|string $token * * @return bool */ public function isA($value, $token) { return $this->getType($value) === $token; } /** * Moves the lookahead token forward. * * @return mixed[]|null The next token or NULL if there are no more tokens ahead. * @psalm-return Token|null */ public function peek() { if (isset($this->tokens[$this->position + $this->peek])) { return $this->tokens[$this->position + $this->peek++]; } return null; } /** * Peeks at the next token, returns it and immediately resets the peek. * * @return mixed[]|null The next token or NULL if there are no more tokens ahead. * @psalm-return Token|null */ public function glimpse() { $peek = $this->peek(); $this->peek = 0; return $peek; } /** * Scans the input string for tokens. * * @param string $input A query string. * * @return void */ protected function scan($input) { if (! isset($this->regex)) { $this->regex = sprintf( '/(%s)|%s/%s', implode(')|(', $this->getCatchablePatterns()), implode('|', $this->getNonCatchablePatterns()), $this->getModifiers() ); } $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE; $matches = preg_split($this->regex, $input, -1, $flags); if ($matches === false) { // Work around https://bugs.php.net/78122 $matches = [[$input, 0]]; } foreach ($matches as $match) { // Must remain before 'value' assignment since it can change content $firstMatch = $match[0]; $type = $this->getType($firstMatch); $this->tokens[] = new Token( $firstMatch, $type, $match[1] ); } } /** * Gets the literal for a given token. * * @param T $token * * @return int|string */ public function getLiteral($token) { if ($token instanceof UnitEnum) { return get_class($token) . '::' . $token->name; } $className = static::class; $reflClass = new ReflectionClass($className); $constants = $reflClass->getConstants(); foreach ($constants as $name => $value) { if ($value === $token) { return $className . '::' . $name; } } return $token; } /** * Regex modifiers * * @return string */ protected function getModifiers() { return 'iu'; } /** * Lexical catchable patterns. * * @return string[] */ abstract protected function getCatchablePatterns(); /** * Lexical non-catchable patterns. * * @return string[] */ abstract protected function getNonCatchablePatterns(); /** * Retrieve token type. Also processes the token value if necessary. * * @param string $value * * @return T|null * * @param-out V $value */ abstract protected function getType(&$value); } PKn Z6qoolexer/README.mdnu[# Doctrine Lexer [![Build Status](https://github.com/doctrine/lexer/workflows/Continuous%20Integration/badge.svg)](https://github.com/doctrine/lexer/actions) Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers. This lexer is used in Doctrine Annotations and in Doctrine ORM (DQL). https://www.doctrine-project.org/projects/lexer.html PKn Z`XQ)) lexer/LICENSEnu[Copyright (c) 2006-2018 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. PKn ZoKwwlexer/UPGRADE.mdnu[Note about upgrading: Doctrine uses static and runtime mechanisms to raise awareness about deprecated code. - Use of `@deprecated` docblock that is detected by IDEs (like PHPStorm) or Static Analysis tools (like Psalm, phpstan) - Use of our low-overhead runtime deprecation API, details: https://github.com/doctrine/deprecations/ # Upgrade to 2.0.0 `AbstractLexer::glimpse()` and `AbstractLexer::peek()` now return instances of `Doctrine\Common\Lexer\Token`, which is an array-like class Using it as an array is deprecated in favor of using properties of that class. Using `count()` on it is deprecated with no replacement. PKn Zne2deprecations/phpcs.xmlnu[PKn Z.͚deprecations/composer.jsonnu[PKn Z#inflector/lib/Doctrine/Inflector/Rules/Spanish/Uninflected.phpnu[PKn Zj?jj8inflector/lib/Doctrine/Inflector/Rules/Spanish/Rules.phpnu[PKn Z͕99>ʲinflector/lib/Doctrine/Inflector/Rules/Spanish/Inflectible.phpnu[PKn Z;0Kqinflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/InflectorFactory.phpnu[PKn ZٮdddFinflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Uninflected.phpnu[PKn ZTrr@inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Rules.phpnu[PKn Z{<F}inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Inflectible.phpnu[PKn Z7inflector/lib/Doctrine/Inflector/Rules/Substitution.phpnu[PKn ZY?Cinflector/lib/Doctrine/Inflector/Rules/English/InflectorFactory.phpnu[PKn Z&'> inflector/lib/Doctrine/Inflector/Rules/English/Uninflected.phpnu[PKn ZDjj8 inflector/lib/Doctrine/Inflector/Rules/English/Rules.phpnu[PKn Z. 8-8->inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.phpnu[PKn Zm\\8inflector/lib/Doctrine/Inflector/Rules/Substitutions.phpnu[PKn Z~2BEinflector/lib/Doctrine/Inflector/Rules/French/InflectorFactory.phpnu[PKn Z=inflector/lib/Doctrine/Inflector/Rules/French/Uninflected.phpnu[PKn Zldii7"inflector/lib/Doctrine/Inflector/Rules/French/Rules.phpnu[PKn ZyXVV=%inflector/lib/Doctrine/Inflector/Rules/French/Inflectible.phpnu[PKn Zv掸3-inflector/lib/Doctrine/Inflector/Rules/Patterns.phpnu[PKn ZKHW&&/0inflector/lib/Doctrine/Inflector/Rules/Word.phpnu[PKn Z C42inflector/lib/Doctrine/Inflector/Rules/Turkish/InflectorFactory.phpnu[PKn Z>Yεgg>t4inflector/lib/Doctrine/Inflector/Rules/Turkish/Uninflected.phpnu[PKn Zڃjj8I7inflector/lib/Doctrine/Inflector/Rules/Turkish/Rules.phpnu[PKn ZJ>;inflector/lib/Doctrine/Inflector/Rules/Turkish/Inflectible.phpnu[PKn Zh%AS:w?inflector/lib/Doctrine/Inflector/Rules/Transformations.phpnu[PKn ZfP  2iBinflector/lib/Doctrine/Inflector/Rules/Ruleset.phpnu[PKn Z[_i8Einflector/lib/Doctrine/Inflector/CachedWordInflector.phpnu[PKn Z;D;Hinflector/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.phpnu[PKn Z]9@q5:Oinflector/lib/Doctrine/Inflector/InflectorFactory.phpnu[PKn ZI6-Uinflector/lib/Doctrine/Inflector/NoopWordInflector.phpnu[PKn ZKڮ-\Vinflector/lib/Doctrine/Inflector/Language.phpnu[PKn Zx%%=gXinflector/lib/Doctrine/Inflector/LanguageInflectorFactory.phpnu[PKn Zw)Q  [inflector/README.mdnu[PKn Z9))I^inflector/LICENSEnu[PKn ZW||binflector/docs/en/index.rstnu[PKn Zz|instantiator/composer.jsonnu[PKn Zz.WWMʂinstantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.phpnu[PKn Z$8Minstantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.phpnu[PKn ZfGinstantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.phpnu[PKn Zyaݒ7*instantiator/src/Doctrine/Instantiator/Instantiator.phpnu[PKn Z.U@#instantiator/src/Doctrine/Instantiator/InstantiatorInterface.phpnu[PKn Zxxd#instantiator/.doctrine-project.jsonnu[PKn Z4@++instantiator/README.mdnu[PKn Z ͂$$einstantiator/LICENSEnu[PKn Zv&& instantiator/docs/en/sidebar.rstnu[PKn ZHXCinstantiator/docs/en/index.rstnu[PKn Zwpinstantiator/psalm.xmlnu[PKn Zﻦinstantiator/CONTRIBUTING.mdnu[PKn Zhlexer/composer.jsonnu[PKn Z+{ lexer/src/Token.phpnu[PKn Z0(lexer/src/AbstractLexer.phpnu[PKn Z6qoo>lexer/README.mdnu[PKn Z`XQ)) lexer/LICENSEnu[PKn ZoKwwRlexer/UPGRADE.mdnu[PKFF