From d456901ad011ed674d5b3e7eacc356e26146042f Mon Sep 17 00:00:00 2001 From: Frankie Jarrett Date: Tue, 28 Dec 2021 18:07:42 -0600 Subject: [PATCH 01/14] Add salutations and suffixes --- src/Language/English.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/Language/English.php b/src/Language/English.php index 08d9585..4035552 100644 --- a/src/Language/English.php +++ b/src/Language/English.php @@ -12,23 +12,41 @@ class English implements LanguageInterface '3rd' => '3rd', '4th' => '4th', '5th' => '5th', + '6th' => '6th', + '7th' => '7th', + '8th' => '8th', + '9th' => '9th', + '10th' => '10th', 'i' => 'I', 'ii' => 'II', 'iii' => 'III', 'iv' => 'IV', 'v' => 'V', + 'vi' => 'VI', + 'vii' => 'VII', + 'vii' => 'VIII', + 'ix' => 'IX', + 'x' => 'X', 'apr' => 'APR', 'cme' => 'CME', + 'dc' => 'DC', 'dds' => 'DDS', 'dmd' => 'DMD', + 'do' => 'DO', + 'dsw' => 'DSW', 'dvm' => 'DVM', 'esq' => 'Esq', + 'esquire' => 'Esquire', 'jr' => 'Jr', 'junior' => 'Junior', + 'lcsw' => 'LCSW', 'ma' => 'MA', 'md' => 'MD', + 'ms' => 'MS', + 'msw' => 'MSW', 'pe' => 'PE', 'phd' => 'PhD', + 'psyd' => 'PsyD', 'rph' => 'RPh', 'senior' => 'Senior', 'sr' => 'Sr', @@ -37,9 +55,13 @@ class English implements LanguageInterface const SALUTATIONS = [ 'dr' => 'Dr.', 'fr' => 'Fr.', + 'hon' => 'Hon.', + 'honorable' => 'The Honorable', + 'the honorable' => 'The Honorable', 'madam' => 'Madam', 'master' => 'Mr.', 'miss' => 'Miss', + 'missus' => 'Mrs.', 'mister' => 'Mr.', 'mr' => 'Mr.', 'mrs' => 'Mrs.', From 8e41af7f460f3e68050ad65c9404e2b2b16d66b4 Mon Sep 17 00:00:00 2001 From: Frankie Jarrett Date: Tue, 28 Dec 2021 18:16:48 -0600 Subject: [PATCH 02/14] Standardize on shorthand for Honorable --- src/Language/English.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Language/English.php b/src/Language/English.php index 4035552..235eeea 100644 --- a/src/Language/English.php +++ b/src/Language/English.php @@ -56,8 +56,8 @@ class English implements LanguageInterface 'dr' => 'Dr.', 'fr' => 'Fr.', 'hon' => 'Hon.', - 'honorable' => 'The Honorable', - 'the honorable' => 'The Honorable', + 'honorable' => 'Hon.', + 'the honorable' => 'Hon.', 'madam' => 'Madam', 'master' => 'Mr.', 'miss' => 'Miss', From 7f73effcfbbb0df9f5c0e1ccf9f80342893b0584 Mon Sep 17 00:00:00 2001 From: Frankie Jarrett Date: Tue, 28 Dec 2021 18:17:22 -0600 Subject: [PATCH 03/14] Add EMBA and MBA --- src/Language/English.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Language/English.php b/src/Language/English.php index 235eeea..8acf644 100644 --- a/src/Language/English.php +++ b/src/Language/English.php @@ -35,12 +35,14 @@ class English implements LanguageInterface 'do' => 'DO', 'dsw' => 'DSW', 'dvm' => 'DVM', + 'emba' => 'EMBA', 'esq' => 'Esq', 'esquire' => 'Esquire', 'jr' => 'Jr', 'junior' => 'Junior', 'lcsw' => 'LCSW', 'ma' => 'MA', + 'mba' => 'MBA', 'md' => 'MD', 'ms' => 'MS', 'msw' => 'MSW', From d154532cd8e996e91af58c7bb0f5a67cc38d03f1 Mon Sep 17 00:00:00 2001 From: Zachary Miller Date: Sun, 10 May 2026 16:32:29 -0400 Subject: [PATCH 04/14] Fix duplicate 'vii' key in English suffixes PR #54 (now merged) contained a typo: 'vii' => 'VIII' as a duplicate of 'vii' => 'VII'. PHP silently overwrites duplicate array keys, so 'vii' was mapping to 'VIII' and 'viii' was never defined. Corrected the second key to 'viii' so both Roman numerals work as intended. --- src/Language/English.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/English.php b/src/Language/English.php index 8acf644..3cf9dca 100644 --- a/src/Language/English.php +++ b/src/Language/English.php @@ -24,7 +24,7 @@ class English implements LanguageInterface 'v' => 'V', 'vi' => 'VI', 'vii' => 'VII', - 'vii' => 'VIII', + 'viii' => 'VIII', 'ix' => 'IX', 'x' => 'X', 'apr' => 'APR', From 6b9a99df4661cd65dd46f401575d9361b605e2c0 Mon Sep 17 00:00:00 2001 From: Zachary Miller Date: Sun, 10 May 2026 16:35:53 -0400 Subject: [PATCH 05/14] Rename namespace TheIconic\NameParser to CodeByZach\NameParser Full rename across 25 src/ and 13 tests/ files. Tests now live under Tests\CodeByZach\NameParser via composer.json autoload-dev split. - composer.json: package renamed to codebyzach/name-parser; autoload split into src (CodeByZach\NameParser\*) and dev tests (Tests\CodeByZach\NameParser\*); Zachary Miller added to authors alongside The Iconic - src/Name.php: hardcoded PARTS_NAMESPACE constant updated - tests/bootstrap.php: hardcoded PHPMock::defineFunctionMock target updated (kept as the src namespace, not the Tests prefix, since the mocked function_exists call lives in src/Part/AbstractPart.php) - README.md: composer require line updated to codebyzach/name-parser Pure mechanical rewrite, zero behavior change. PHPUnit run deferred to Phase 3 since PHPUnit ^7 doesn't install on PHP 8.x. --- README.md | 18 +++++++++--------- composer.json | 13 +++++++++++-- src/Language/English.php | 4 ++-- src/Language/German.php | 4 ++-- src/LanguageInterface.php | 2 +- src/Mapper/AbstractMapper.php | 6 +++--- src/Mapper/FirstnameMapper.php | 12 ++++++------ src/Mapper/InitialMapper.php | 6 +++--- src/Mapper/LastnameMapper.php | 18 +++++++++--------- src/Mapper/MiddlenameMapper.php | 10 +++++----- src/Mapper/NicknameMapper.php | 6 +++--- src/Mapper/SalutationMapper.php | 6 +++--- src/Mapper/SuffixMapper.php | 6 +++--- src/Name.php | 8 ++++---- src/Parser.php | 20 ++++++++++---------- src/Part/AbstractPart.php | 2 +- src/Part/Firstname.php | 2 +- src/Part/GivenNamePart.php | 2 +- src/Part/Initial.php | 2 +- src/Part/Lastname.php | 2 +- src/Part/LastnamePrefix.php | 2 +- src/Part/Middlename.php | 2 +- src/Part/NamePart.php | 2 +- src/Part/Nickname.php | 2 +- src/Part/PreNormalizedPart.php | 2 +- src/Part/Salutation.php | 2 +- src/Part/Suffix.php | 2 +- tests/GermanParserTest.php | 4 ++-- tests/Mapper/AbstractMapperTest.php | 2 +- tests/Mapper/FirstnameMapperTest.php | 8 ++++---- tests/Mapper/InitialMapperTest.php | 10 +++++----- tests/Mapper/LastnameMapperTest.php | 12 ++++++------ tests/Mapper/MiddlenameMapperTest.php | 10 +++++----- tests/Mapper/NicknameMapperTest.php | 6 +++--- tests/Mapper/SalutationMapperTest.php | 10 +++++----- tests/Mapper/SuffixMapperTest.php | 10 +++++----- tests/NameTest.php | 18 +++++++++--------- tests/ParserTest.php | 6 +++--- tests/Part/AbstractPartTest.php | 2 +- tests/Part/NormalisationTest.php | 2 +- tests/bootstrap.php | 2 +- 41 files changed, 137 insertions(+), 128 deletions(-) diff --git a/README.md b/README.md index c3d3122..3b7a1ae 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ More than 60 different successfully parsed name patterns can be found in the ## Setup ```$xslt -composer require theiconic/name-parser +composer require codebyzach/name-parser ``` ## Usage @@ -73,7 +73,7 @@ composer require theiconic/name-parser ```php parse($input); @@ -125,27 +125,27 @@ echo $name->getFullName(); // J. Peter M. Schluter ### Setting Languages ```php -$parser = new TheIconic\NameParser\Parser([ - new TheIconic\NameParser\Language\English(), //default - new TheIconic\NameParser\Language\German(), +$parser = new CodeByZach\NameParser\Parser([ + new CodeByZach\NameParser\Language\English(), //default + new CodeByZach\NameParser\Language\German(), ]) ``` ### Setting nickname delimiters ```php -$parser = new TheIconic\NameParser\Parser(); +$parser = new CodeByZach\NameParser\Parser(); $parser->setNicknameDelimiters(['(' => ')']); ``` ### Setting whitespace characters ```php -$parser = new TheIconic\NameParser\Parser(); +$parser = new CodeByZach\NameParser\Parser(); $parser->setWhitespace("\t _."); ``` ### Limiting the position of salutations ```php -$parser = new TheIconic\NameParser\Parser(); +$parser = new CodeByZach\NameParser\Parser(); $parser->setMaxSalutationIndex(2); ``` This will require salutations to appear within the @@ -156,7 +156,7 @@ the first half of the name parts. ### Adjusting combined initials support ```php -$parser = new TheIconic\NameParser\Parser(); +$parser = new CodeByZach\NameParser\Parser(); $parser->setMaxCombinedInitials(3); ``` Combined initials are combinations of several diff --git a/composer.json b/composer.json index c13fd59..7e8a5b1 100644 --- a/composer.json +++ b/composer.json @@ -1,9 +1,13 @@ { - "name": "theiconic/name-parser", + "name": "codebyzach/name-parser", "description": "PHP library for parsing a string containing a full name into its parts", "type": "library", "license": "MIT", "authors": [ + { + "name": "Zachary Miller", + "email": "codebyzach@gmail.com" + }, { "name": "The Iconic", "email": "engineering@theiconic.com.au" @@ -19,7 +23,12 @@ }, "autoload": { "psr-4": { - "TheIconic\\NameParser\\": ["src/", "tests/"] + "CodeByZach\\NameParser\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\CodeByZach\\NameParser\\": "tests/" } } } diff --git a/src/Language/English.php b/src/Language/English.php index 3cf9dca..1ba818d 100644 --- a/src/Language/English.php +++ b/src/Language/English.php @@ -1,8 +1,8 @@ Date: Sun, 10 May 2026 16:48:01 -0400 Subject: [PATCH 06/14] Modernize: PHP 8.2+, PHPUnit 11, drop Travis/Scrutinizer PHP / Composer: - Bump php floor from >=7.1 to ^8.2; declare ext-mbstring as required (the AbstractPart::camelcaseReplace fallback produces incorrect Unicode output without it) - Replace PHPUnit ^7 with ^11; replace php-mock-phpunit ^2.1 with ^2.15 - Drop php-coveralls (Coveralls.io reporting no longer used) - Add phpstan ^1.12 and laravel/pint ^1.18 as dev tooling - Split autoload: src under CodeByZach\NameParser, tests under Tests\CodeByZach\NameParser via autoload-dev (was combined before) - Add composer scripts: test, lint, lint:fix, analyse - Sort require-dev and scripts alphabetically; enable sort-packages - Add .tool-versions pinning php 8.4 for local dev (mise/asdf) PHPUnit 11 schema migration: - Rewrite phpunit.xml.dist to PHPUnit 11 schema ( not ; drop deprecated logging targets; cacheDirectory; failOnWarning/Risky) - Migrate three @dataProvider PHPDoc annotations to #[DataProvider] attributes (ParserTest, GermanParserTest, AbstractMapperTestCase) - Make all provider() methods static (PHPUnit 11 requirement) - Rename AbstractMapperTest.php to AbstractMapperTestCase.php so PHPUnit doesn't try to discover tests in the abstract base - Replace deprecated getMockForAbstractClass() in AbstractPartTest with PHP 8 anonymous classes (PHPUnit 12 will remove the mock helper) - Move PHPMock::defineFunctionMock from bootstrap.php into NormalisationTest::setUpBeforeClass (the static trait call is deprecated when not on a class using the trait) - Convert SuffixMapperTest data sets to use 'arguments' named key so PHPUnit's argument unpacking doesn't mix named and positional args - Add missing use statements in test files for Parser, Name, AbstractPart, Firstname, Lastname, and the Mapper classes (became necessary after Phase 2 split tests into Tests\ namespace) PHP 8.4 explicit-nullable migration: - Name::__construct: array $parts = null -> ?array $parts = null - PreNormalizedPart::__construct, LastnamePrefix::__construct: same fix for the $normalized parameter Removed: - .travis.yml (Travis CI free tier dead since 2020) - .scrutinizer.yml (Scrutinizer-CI replaced by PHPStan) - composer.lock (regenerated under new constraints) Test suite: 131 tests, 235 assertions, 0 errors, 0 warnings, 0 deprecations on PHP 8.4 / PHPUnit 11.5.55. --- .gitignore | 1 + .scrutinizer.yml | 8 - .tool-versions | 1 + .travis.yml | 21 - composer.json | 19 +- composer.lock | 2166 ++++++++--------- phpunit.xml.dist | 34 +- src/Name.php | 2 +- src/Part/LastnamePrefix.php | 2 +- src/Part/PreNormalizedPart.php | 2 +- tests/GermanParserTest.php | 14 +- ...perTest.php => AbstractMapperTestCase.php} | 10 +- tests/Mapper/FirstnameMapperTest.php | 7 +- tests/Mapper/InitialMapperTest.php | 7 +- tests/Mapper/LastnameMapperTest.php | 7 +- tests/Mapper/MiddlenameMapperTest.php | 9 +- tests/Mapper/NicknameMapperTest.php | 7 +- tests/Mapper/SalutationMapperTest.php | 7 +- tests/Mapper/SuffixMapperTest.php | 43 +- tests/NameTest.php | 4 +- tests/ParserTest.php | 14 +- tests/Part/AbstractPartTest.php | 15 +- tests/Part/NormalisationTest.php | 7 + tests/bootstrap.php | 6 +- 24 files changed, 1080 insertions(+), 1333 deletions(-) delete mode 100644 .scrutinizer.yml create mode 100644 .tool-versions delete mode 100644 .travis.yml rename tests/Mapper/{AbstractMapperTest.php => AbstractMapperTestCase.php} (70%) diff --git a/.gitignore b/.gitignore index 4bb9daf..ecfa7a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /vendor/ /tests/coverage +/.phpunit.cache/ phpunit.xml diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 6fc3be8..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,8 +0,0 @@ -checks: - php: true -filter: - excluded_paths: - - vendor/ - - tests/ - paths: - - src/* diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..de9d6ca --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +php 8.4 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 101124e..0000000 --- a/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: php -sudo: false -php: - - "7.1" - - "7.2" -env: - global: - - CC_TEST_REPORTER_ID=e52166dfd6d88c1c44d25f8ff60dfad344267093392ea772683f9d84aaa26998 -install: - - composer install - - composer dump-autoload -o -before_script: - - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - - chmod +x ./cc-test-reporter - - ./cc-test-reporter before-build -script: - - mkdir -p build/logs - - vendor/bin/phpunit --coverage-clover build/logs/clover.xml -after_script: - - travis_retry php vendor/bin/php-coveralls -v - - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT diff --git a/composer.json b/composer.json index 7e8a5b1..a57af0f 100644 --- a/composer.json +++ b/composer.json @@ -14,12 +14,14 @@ } ], "require": { - "php": ">=7.1" + "php": "^8.2", + "ext-mbstring": "*" }, "require-dev": { - "phpunit/phpunit": "^7.0", - "php-coveralls/php-coveralls": "^2.1", - "php-mock/php-mock-phpunit": "^2.1" + "laravel/pint": "^1.18", + "php-mock/php-mock-phpunit": "^2.15", + "phpstan/phpstan": "^1.12", + "phpunit/phpunit": "^11.0" }, "autoload": { "psr-4": { @@ -30,5 +32,14 @@ "psr-4": { "Tests\\CodeByZach\\NameParser\\": "tests/" } + }, + "scripts": { + "analyse": "phpstan analyse", + "lint": "pint --test", + "lint:fix": "pint", + "test": "phpunit" + }, + "config": { + "sort-packages": true } } diff --git a/composer.lock b/composer.lock index 3484389..b51a2c4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,42 +4,49 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f6d73c5b1ffd335d5886f0b5ed50e259", + "content-hash": "64efbb9a09b6155c57bb901ef9275c87", "packages": [], "packages-dev": [ { - "name": "doctrine/instantiator", - "version": "1.1.0", + "name": "laravel/pint", + "version": "v1.29.1", "source": { "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + "url": "https://github.com/laravel/pint.git", + "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "url": "https://api.github.com/repos/laravel/pint/zipball/0770e9b7fafd50d4586881d456d6eb41c9247a80", + "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80", "shasum": "" }, "require": { - "php": "^7.1" + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.2.0" }, "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } + "friendsofphp/php-cs-fixer": "^3.95.1", + "illuminate/view": "^12.56.0", + "larastan/larastan": "^3.9.6", + "laravel-zero/framework": "^12.1.0", + "mockery/mockery": "^1.6.12", + "nunomaduro/termwind": "^2.4.0", + "pestphp/pest": "^3.8.6", + "shipfastlabs/agent-detector": "^1.1.3" }, + "bin": [ + "builds/pint" + ], + "type": "project", "autoload": { "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" } }, "notification-url": "https://packagist.org/downloads/", @@ -48,272 +55,170 @@ ], "authors": [ { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" } ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", "keywords": [ - "constructor", - "instantiate" - ], - "time": "2017-07-22T11:58:36+00:00" + "dev", + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2026-04-20T15:26:14+00:00" }, { - "name": "guzzlehttp/guzzle", - "version": "6.3.3", + "name": "myclabs/deep-copy", + "version": "1.13.4", "source": { "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4", - "php": ">=5.5" + "php": "^7.1 || ^8.0" }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.0" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, - "suggest": { - "psr/log": "Required for using the Log middleware" + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.3-dev" - } - }, "autoload": { "files": [ - "src/functions_include.php" + "src/DeepCopy/deep_copy.php" ], "psr-4": { - "GuzzleHttp\\": "src/" + "DeepCopy\\": "src/DeepCopy/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", + "description": "Create deep copies (clones) of your objects", "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2018-04-22T15:46:56+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "v1.3.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "shasum": "" - }, - "require": { - "php": ">=5.5.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" + "clone", + "copy", + "duplicate", + "object", + "object graph" ], - "authors": [ + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" } ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "time": "2016-12-20T10:07:11+00:00" + "time": "2025-08-01T08:46:24+00:00" }, { - "name": "guzzlehttp/psr7", - "version": "1.4.2", + "name": "nikic/php-parser", + "version": "v5.7.0", "source": { "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] + "PhpParser\\": "lib/PhpParser" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" + "name": "Nikita Popov" } ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "request", - "response", - "stream", - "uri", - "url" - ], - "time": "2017-03-20T17:10:46+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.8.1", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", - "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "replace": { - "myclabs/deep-copy": "self.version" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", + "description": "A PHP parser written in PHP", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "parser", + "php" ], - "time": "2018-06-11T23:09:50+00:00" + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + }, + "time": "2025-12-06T11:56:16+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.1", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -343,24 +248,34 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", - "version": "1.0.1", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -390,120 +305,45 @@ } ], "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" - }, - { - "name": "php-coveralls/php-coveralls", - "version": "v2.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-coveralls/php-coveralls.git", - "reference": "3b00c229726f892bfdadeaf01ea430ffd04a939d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/3b00c229726f892bfdadeaf01ea430ffd04a939d", - "reference": "3b00c229726f892bfdadeaf01ea430ffd04a939d", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-simplexml": "*", - "guzzlehttp/guzzle": "^6.0", - "php": "^5.5 || ^7.0", - "psr/log": "^1.0", - "symfony/config": "^2.1 || ^3.0 || ^4.0", - "symfony/console": "^2.1 || ^3.0 || ^4.0", - "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0", - "symfony/yaml": "^2.0 || ^3.0 || ^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0" - }, - "suggest": { - "symfony/http-kernel": "Allows Symfony integration" - }, - "bin": [ - "bin/php-coveralls" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "autoload": { - "psr-4": { - "PhpCoveralls\\": "src/" - } + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kitamura Satoshi", - "email": "with.no.parachute@gmail.com", - "homepage": "https://www.facebook.com/satooshi.jp", - "role": "Original creator" - }, - { - "name": "Takashi Matsuo", - "email": "tmatsuo@google.com" - }, - { - "name": "Google Inc" - }, - { - "name": "Dariusz Ruminski", - "email": "dariusz.ruminski@gmail.com", - "homepage": "https://github.com/keradus" - }, - { - "name": "Contributors", - "homepage": "https://github.com/php-coveralls/php-coveralls/graphs/contributors" - } - ], - "description": "PHP client library for Coveralls API", - "homepage": "https://github.com/php-coveralls/php-coveralls", - "keywords": [ - "ci", - "coverage", - "github", - "test" - ], - "time": "2018-05-22T23:11:08+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { "name": "php-mock/php-mock", - "version": "2.0.0", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/php-mock/php-mock.git", - "reference": "22d297231118e6fd5b9db087fbe1ef866c2b95d2" + "reference": "b59734f19765296bb0311942850d02288a224890" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-mock/php-mock/zipball/22d297231118e6fd5b9db087fbe1ef866c2b95d2", - "reference": "22d297231118e6fd5b9db087fbe1ef866c2b95d2", + "url": "https://api.github.com/repos/php-mock/php-mock/zipball/b59734f19765296bb0311942850d02288a224890", + "reference": "b59734f19765296bb0311942850d02288a224890", "shasum": "" }, "require": { - "php": ">=5.6", - "phpunit/php-text-template": "^1" + "php": "^5.6 || ^7.0 || ^8.0", + "phpunit/php-text-template": "^1 || ^2 || ^3 || ^4 || ^5 || ^6" }, "replace": { "malkusch/php-mock": "*" }, "require-dev": { - "phpunit/phpunit": "^5.7" + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0", + "squizlabs/php_codesniffer": "^3.8" }, "suggest": { "php-mock/php-mock-phpunit": "Allows integration into PHPUnit testcase with the trait PHPMock." }, "type": "library", "autoload": { + "files": [ + "autoload.php" + ], "psr-4": { "phpmock\\": [ "classes/", @@ -532,31 +372,42 @@ "mock", "stub", "test", - "test double" + "test double", + "testing" + ], + "support": { + "issues": "https://github.com/php-mock/php-mock/issues", + "source": "https://github.com/php-mock/php-mock/tree/2.7.0" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } ], - "time": "2017-02-17T20:52:52+00:00" + "time": "2026-02-06T07:39:37+00:00" }, { "name": "php-mock/php-mock-integration", - "version": "2.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/php-mock/php-mock-integration.git", - "reference": "5a0d7d7755f823bc2a230cfa45058b40f9013bc4" + "reference": "cbbf39705ec13dece5b04133cef4e2fd3137a345" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-mock/php-mock-integration/zipball/5a0d7d7755f823bc2a230cfa45058b40f9013bc4", - "reference": "5a0d7d7755f823bc2a230cfa45058b40f9013bc4", + "url": "https://api.github.com/repos/php-mock/php-mock-integration/zipball/cbbf39705ec13dece5b04133cef4e2fd3137a345", + "reference": "cbbf39705ec13dece5b04133cef4e2fd3137a345", "shasum": "" }, "require": { "php": ">=5.6", - "php-mock/php-mock": "^2", - "phpunit/php-text-template": "^1" + "php-mock/php-mock": "^2.5", + "phpunit/php-text-template": "^1 || ^2 || ^3 || ^4 || ^5 || ^6" }, "require-dev": { - "phpunit/phpunit": "^4|^5" + "phpunit/phpunit": "^5.7.27 || ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || ^13" }, "type": "library", "autoload": { @@ -587,26 +438,39 @@ "test", "test double" ], - "time": "2017-02-17T21:31:34+00:00" + "support": { + "issues": "https://github.com/php-mock/php-mock-integration/issues", + "source": "https://github.com/php-mock/php-mock-integration/tree/3.1.0" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } + ], + "time": "2026-02-06T07:44:43+00:00" }, { "name": "php-mock/php-mock-phpunit", - "version": "2.1.1", + "version": "2.15.0", "source": { "type": "git", "url": "https://github.com/php-mock/php-mock-phpunit.git", - "reference": "ff1cc1d4e7478ce74221e05742588619bee84f69" + "reference": "701df15b183f25af663af134eb71353cd838b955" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-mock/php-mock-phpunit/zipball/ff1cc1d4e7478ce74221e05742588619bee84f69", - "reference": "ff1cc1d4e7478ce74221e05742588619bee84f69", + "url": "https://api.github.com/repos/php-mock/php-mock-phpunit/zipball/701df15b183f25af663af134eb71353cd838b955", + "reference": "701df15b183f25af663af134eb71353cd838b955", "shasum": "" }, "require": { "php": ">=7", - "php-mock/php-mock-integration": "^2", - "phpunit/phpunit": "^6 || ^7" + "php-mock/php-mock-integration": "^3.0", + "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17 || ^11 || ^12.0.9 || ^13" + }, + "require-dev": { + "mockery/mockery": "^1.3.6" }, "type": "library", "autoload": { @@ -639,261 +503,265 @@ "phpunit", "stub", "test", - "test double" + "test double", + "testing" + ], + "support": { + "issues": "https://github.com/php-mock/php-mock-phpunit/issues", + "source": "https://github.com/php-mock/php-mock-phpunit/tree/2.15.0" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } ], - "time": "2018-04-06T13:54:43+00:00" + "time": "2026-02-06T09:12:10+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" - }, + "name": "phpstan/phpstan", + "version": "1.12.33", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/37982d6fc7cbb746dda7773530cda557cdf119e1", + "reference": "37982d6fc7cbb746dda7773530cda557cdf119e1", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.2|^8.0" }, - "require-dev": { - "phpunit/phpunit": "^4.6" + "conflict": { + "phpstan/phpstan-shim": "*" }, + "bin": [ + "phpstan", + "phpstan.phar" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] - } + "files": [ + "bootstrap.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", + "description": "PHPStan - PHP Static Analysis Tool", "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", + "dev", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2026-02-28T20:30:03+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.0", + "name": "phpunit/php-code-coverage", + "version": "11.0.12", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2c1ed04922802c15e1de5d7447b4856de949cf56", + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56", "shasum": "" }, "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.7.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.1", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.3.1" }, "require-dev": { - "doctrine/instantiator": "~1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" + "phpunit/phpunit": "^11.5.46" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-main": "11.0.x-dev" } }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.12" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" } ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "time": "2025-12-24T07:01:01+00:00" }, { - "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "name": "phpunit/php-file-iterator", + "version": "5.1.1", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/2f3a64888c814fc235386b7387dd5b5ed92ad903", + "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": ">=8.2" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "5.1-dev" } }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "time": "2017-07-14T14:27:02+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "1.7.6", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", - "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" ], - "authors": [ + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" }, { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator", + "type": "tidelift" } ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2018-04-18T13:57:24+00:00" + "time": "2026-02-02T13:52:54+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "6.0.7", + "name": "phpunit/php-invoker", + "version": "5.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a", - "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.1", - "phpunit/php-file-iterator": "^2.0", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" }, "suggest": { - "ext-xdebug": "^2.6.0" + "ext-pcntl": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -912,80 +780,50 @@ "role": "lead" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", "keywords": [ - "coverage", - "testing", - "xunit" + "process" ], - "time": "2018-06-01T07:51:50+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cecbc684605bb0cc288828eb5d65d93d5c676d3c", - "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "url": "https://github.com/sebastianbergmann", + "type": "github" } ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2018-06-11T11:44:00+00:00" + "time": "2024-07-03T05:07:44+00:00" }, { "name": "phpunit/php-text-template", - "version": "1.2.1", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -1007,32 +845,43 @@ "keywords": [ "template" ], - "time": "2015-06-21T13:50:34+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" }, { "name": "phpunit/php-timer", - "version": "2.0.0", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", - "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -1056,106 +905,64 @@ "keywords": [ "timer" ], - "time": "2018-02-01T13:07:23+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", - "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", - "shasum": "" + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" }, - "require": { - "ext-tokenizer": "*", - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "url": "https://github.com/sebastianbergmann", + "type": "github" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2018-02-01T13:16:43+00:00" + "time": "2024-07-03T05:09:35+00:00" }, { "name": "phpunit/phpunit", - "version": "7.2.4", + "version": "11.5.55", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "00bc0b93f0ff4f557e9ea766557fde96da9a03dd" + "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/00bc0b93f0ff4f557e9ea766557fde96da9a03dd", - "reference": "00bc0b93f0ff4f557e9ea766557fde96da9a03dd", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/adc7262fccc12de2b30f12a8aa0b33775d814f00", + "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "^1.7", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.1", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.7", - "phpunit/php-file-iterator": "^2.0", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.0", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpunit/phpunit-mock-objects": "*" - }, - "require-dev": { - "ext-pdo": "*" + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.12", + "phpunit/php-file-iterator": "^5.1.1", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.3", + "sebastian/comparator": "^6.3.3", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.1", + "sebastian/exporter": "^6.3.2", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/recursion-context": "^6.0.3", + "sebastian/type": "^5.1.3", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -1163,10 +970,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.2-dev" + "dev-main": "11.5-dev" } }, "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], "classmap": [ "src/" ] @@ -1189,129 +999,173 @@ "testing", "xunit" ], - "time": "2018-06-05T03:40:05+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.55" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2026-02-18T12:37:06+00:00" }, { - "name": "psr/http-message", - "version": "1.0.1", + "name": "sebastian/cli-parser", + "version": "3.0.2", "source": { "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "3.0-dev" } }, "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2016-08-06T14:39:51+00:00" + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" }, { - "name": "psr/log", - "version": "1.0.2", + "name": "sebastian/code-unit", + "version": "3.0.3", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "3.0-dev" } }, "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "time": "2016-10-10T12:19:37+00:00" + "time": "2025-03-19T07:56:08+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1331,34 +1185,50 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:45:54+00:00" }, { "name": "sebastian/comparator", - "version": "3.0.1", + "version": "6.3.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "591a30922f54656695e59b1f39501aec513403da" + "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/591a30922f54656695e59b1f39501aec513403da", - "reference": "591a30922f54656695e59b1f39501aec513403da", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", + "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", "shasum": "" }, "require": { - "php": "^7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "6.3-dev" } }, "autoload": { @@ -1371,6 +1241,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -1382,10 +1256,6 @@ { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", @@ -1395,33 +1265,56 @@ "compare", "equality" ], - "time": "2018-06-14T15:05:28+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2026-01-24T09:26:40+00:00" }, { - "name": "sebastian/diff", - "version": "3.0.1", + "name": "sebastian/complexity", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "366541b989927187c4ca70490a35615d3fef2dce" + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce", - "reference": "366541b989927187c4ca70490a35615d3fef2dce", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", "shasum": "" }, "require": { - "php": "^7.1" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^7.0", - "symfony/process": "^2 || ^3.3 || ^4" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1434,49 +1327,52 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "time": "2018-06-10T07:54:39+00:00" + "time": "2024-07-03T04:49:50+00:00" }, { - "name": "sebastian/environment", - "version": "3.1.0", + "name": "sebastian/diff", + "version": "6.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^6.1" + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1492,43 +1388,60 @@ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" } ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "Xdebug", - "environment", - "hhvm" + "diff", + "udiff", + "unidiff", + "unified diff" ], - "time": "2017-07-01T08:51:00+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" }, { - "name": "sebastian/exporter", - "version": "3.1.0", + "name": "sebastian/environment", + "version": "7.2.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" + "php": ">=8.2" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^11.3" + }, + "suggest": { + "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-main": "7.2-dev" } }, "autoload": { @@ -1542,61 +1455,68 @@ ], "authors": [ { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" + }, + "funding": [ { - "name": "Volker Dusch", - "email": "github@wallbash.com" + "url": "https://github.com/sebastianbergmann", + "type": "github" }, { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" } ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2025-05-21T11:55:47+00:00" }, { - "name": "sebastian/global-state", - "version": "2.0.0", + "name": "sebastian/exporter", + "version": "6.3.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", "shasum": "" }, "require": { - "php": "^7.0" + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "6.3-dev" } }, "autoload": { @@ -1612,41 +1532,82 @@ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ - "global state" + "export", + "exporter" ], - "time": "2017-04-27T15:39:26+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:12:51+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "3.0.3", + "name": "sebastian/global-state", + "version": "7.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "ext-dom": "*", + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -1664,34 +1625,49 @@ "email": "sebastian@phpunit.de" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" }, { - "name": "sebastian/object-reflector", - "version": "1.1.1", + "name": "sebastian/lines-of-code", + "version": "3.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", "shasum": "" }, "require": { - "php": "^7.0" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1706,37 +1682,51 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" }, { - "name": "sebastian/recursion-context", - "version": "3.0.0", + "name": "sebastian/object-enumerator", + "version": "6.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1749,44 +1739,50 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" - }, + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + }, + "funding": [ { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "url": "https://github.com/sebastianbergmann", + "type": "github" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "time": "2024-07-03T05:00:13+00:00" }, { - "name": "sebastian/resource-operations", - "version": "1.0.0", + "name": "sebastian/object-reflector", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { - "php": ">=5.6.0" + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1804,31 +1800,45 @@ "email": "sebastian@phpunit.de" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:01:32+00:00" }, { - "name": "sebastian/version", - "version": "2.0.1", + "name": "sebastian/recursion-context", + "version": "6.0.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1843,436 +1853,238 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "symfony/config", - "version": "v4.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "5ceefc256caecc3e25147c4e5b933de71d0020c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/5ceefc256caecc3e25147c4e5b933de71d0020c4", - "reference": "5ceefc256caecc3e25147c4e5b933de71d0020c4", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "symfony/filesystem": "~3.4|~4.0", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/finder": "<3.4" - }, - "require-dev": { - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~3.4|~4.0", - "symfony/finder": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" - }, - "suggest": { - "symfony/yaml": "To use the yaml reference dumper" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1-dev" - } + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Config\\": "" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" } ], - "description": "Symfony Config Component", - "homepage": "https://symfony.com", - "time": "2018-05-16T14:33:22+00:00" + "time": "2025-08-13T04:42:22+00:00" }, { - "name": "symfony/console", - "version": "v4.1.0", + "name": "sebastian/type", + "version": "5.1.3", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "2d5d973bf9933d46802b01010bd25c800c87c242" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2d5d973bf9933d46802b01010bd25c800c87c242", - "reference": "2d5d973bf9933d46802b01010bd25c800c87c242", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/process": "<3.3" + "php": ">=8.2" }, "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~3.4|~4.0", - "symfony/lock": "~3.4|~4.0", - "symfony/process": "~3.4|~4.0" - }, - "suggest": { - "psr/log-implementation": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-main": "5.1-dev" } }, "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Symfony Console Component", - "homepage": "https://symfony.com", - "time": "2018-05-30T07:26:09+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v4.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "562bf7005b55fd80d26b582d28e3e10f2dd5ae9c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/562bf7005b55fd80d26b582d28e3e10f2dd5ae9c", - "reference": "562bf7005b55fd80d26b582d28e3e10f2dd5ae9c", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "symfony/polyfill-ctype": "~1.8" + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.3" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "url": "https://github.com/sebastianbergmann", + "type": "github" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "https://symfony.com", - "time": "2018-05-30T07:26:09+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.8.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", - "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" }, { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", + "type": "tidelift" } ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "time": "2018-04-30T19:57:29+00:00" + "time": "2025-08-09T06:55:48+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.8.0", + "name": "sebastian/version", + "version": "5.0.2", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "3296adf6a6454a050679cde90f95350ad604b171" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171", - "reference": "3296adf6a6454a050679cde90f95350ad604b171", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8-dev" + "dev-main": "5.0-dev" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "time": "2018-04-26T10:06:28+00:00" - }, - { - "name": "symfony/stopwatch", - "version": "v4.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "07463bbbbbfe119045a24c4a516f92ebd2752784" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/07463bbbbbfe119045a24c4a516f92ebd2752784", - "reference": "07463bbbbbfe119045a24c4a516f92ebd2752784", - "shasum": "" - }, - "require": { - "php": "^7.1.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, + "funding": [ { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://github.com/sebastianbergmann", + "type": "github" } ], - "description": "Symfony Stopwatch Component", - "homepage": "https://symfony.com", - "time": "2018-02-19T16:51:42+00:00" + "time": "2024-10-09T05:16:32+00:00" }, { - "name": "symfony/yaml", - "version": "v4.1.0", + "name": "staabm/side-effects-detector", + "version": "1.0.5", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "80e4bfa9685fc4a09acc4a857ec16974a9cd944e" + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/80e4bfa9685fc4a09acc4a857ec16974a9cd944e", - "reference": "80e4bfa9685fc4a09acc4a857ec16974a9cd944e", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/console": "<3.4" + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" }, "require-dev": { - "symfony/console": "~3.4|~4.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1-dev" - } - }, "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "lib/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://github.com/staabm", + "type": "github" } ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2018-05-30T07:26:09+00:00" + "time": "2024-10-20T05:08:20+00:00" }, { "name": "theseer/tokenizer", - "version": "1.1.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": "^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -2292,66 +2104,28 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a", - "shasum": "" + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "url": "https://github.com/theseer", + "type": "github" } ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2018-01-29T19:49:41+00:00" + "time": "2025-11-17T20:03:58+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.1" + "php": "^8.2", + "ext-mbstring": "*" }, - "platform-dev": [] + "platform-dev": {}, + "plugin-api-version": "2.9.0" } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a4f043e..8992944 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,29 +1,19 @@ - - - - - - - - - - - - - - - src - - tests - - - + failOnWarning="true" + failOnRisky="true"> - + ./tests + + + src + + diff --git a/src/Name.php b/src/Name.php index 24fdfbf..ab2cdf0 100644 --- a/src/Name.php +++ b/src/Name.php @@ -19,7 +19,7 @@ class Name * * @param array|null $parts */ - public function __construct(array $parts = null) + public function __construct(?array $parts = null) { if (null !== $parts) { $this->setParts($parts); diff --git a/src/Part/LastnamePrefix.php b/src/Part/LastnamePrefix.php index 3271f36..6e67bbd 100644 --- a/src/Part/LastnamePrefix.php +++ b/src/Part/LastnamePrefix.php @@ -6,7 +6,7 @@ class LastnamePrefix extends Lastname { protected $normalized = ''; - public function __construct(string $value, string $normalized = null) + public function __construct(string $value, ?string $normalized = null) { $this->normalized = $normalized ?? $value; diff --git a/src/Part/PreNormalizedPart.php b/src/Part/PreNormalizedPart.php index 62704e6..0386df9 100644 --- a/src/Part/PreNormalizedPart.php +++ b/src/Part/PreNormalizedPart.php @@ -6,7 +6,7 @@ abstract class PreNormalizedPart extends AbstractPart { protected $normalized = ''; - public function __construct(string $value, string $normalized = null) + public function __construct(string $value, ?string $normalized = null) { $this->normalized = $normalized ?? $value; diff --git a/tests/GermanParserTest.php b/tests/GermanParserTest.php index fb0db1d..897049d 100644 --- a/tests/GermanParserTest.php +++ b/tests/GermanParserTest.php @@ -2,15 +2,18 @@ namespace Tests\CodeByZach\NameParser; -use PHPUnit\Framework\TestCase; use CodeByZach\NameParser\Language\German; +use CodeByZach\NameParser\Name; +use CodeByZach\NameParser\Parser; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\TestCase; class GermanParserTest extends TestCase { /** * @return array */ - public function provider() + public static function provider() { return [ [ @@ -47,12 +50,7 @@ public function provider() ]; } - /** - * @dataProvider provider - * - * @param $input - * @param $expectation - */ + #[DataProvider('provider')] public function testParse($input, $expectation) { $parser = new Parser([ diff --git a/tests/Mapper/AbstractMapperTest.php b/tests/Mapper/AbstractMapperTestCase.php similarity index 70% rename from tests/Mapper/AbstractMapperTest.php rename to tests/Mapper/AbstractMapperTestCase.php index e53a057..4dac4af 100644 --- a/tests/Mapper/AbstractMapperTest.php +++ b/tests/Mapper/AbstractMapperTestCase.php @@ -2,16 +2,12 @@ namespace Tests\CodeByZach\NameParser\Mapper; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -abstract class AbstractMapperTest extends TestCase +abstract class AbstractMapperTestCase extends TestCase { - /** - * @dataProvider provider - * - * @param $input - * @param $expectation - */ + #[DataProvider('provider')] public function testMap($input, $expectation, $arguments = []) { $mapper = call_user_func_array([$this, 'getMapper'], $arguments); diff --git a/tests/Mapper/FirstnameMapperTest.php b/tests/Mapper/FirstnameMapperTest.php index 5b513a7..014d9fd 100644 --- a/tests/Mapper/FirstnameMapperTest.php +++ b/tests/Mapper/FirstnameMapperTest.php @@ -2,16 +2,17 @@ namespace Tests\CodeByZach\NameParser\Mapper; -use CodeByZach\NameParser\Part\Salutation; +use CodeByZach\NameParser\Mapper\FirstnameMapper; use CodeByZach\NameParser\Part\Firstname; use CodeByZach\NameParser\Part\Lastname; +use CodeByZach\NameParser\Part\Salutation; -class FirstnameMapperTest extends AbstractMapperTest +class FirstnameMapperTest extends AbstractMapperTestCase { /** * @return array */ - public function provider() + public static function provider() { return [ [ diff --git a/tests/Mapper/InitialMapperTest.php b/tests/Mapper/InitialMapperTest.php index 9b19557..6f1c79c 100644 --- a/tests/Mapper/InitialMapperTest.php +++ b/tests/Mapper/InitialMapperTest.php @@ -3,16 +3,17 @@ namespace Tests\CodeByZach\NameParser\Mapper; use CodeByZach\NameParser\Language\English; +use CodeByZach\NameParser\Mapper\InitialMapper; use CodeByZach\NameParser\Part\Initial; -use CodeByZach\NameParser\Part\Salutation; use CodeByZach\NameParser\Part\Lastname; +use CodeByZach\NameParser\Part\Salutation; -class InitialMapperTest extends AbstractMapperTest +class InitialMapperTest extends AbstractMapperTestCase { /** * @return array */ - public function provider() + public static function provider() { return [ [ diff --git a/tests/Mapper/LastnameMapperTest.php b/tests/Mapper/LastnameMapperTest.php index a3d62db..6d57051 100644 --- a/tests/Mapper/LastnameMapperTest.php +++ b/tests/Mapper/LastnameMapperTest.php @@ -3,17 +3,18 @@ namespace Tests\CodeByZach\NameParser\Mapper; use CodeByZach\NameParser\Language\English; -use CodeByZach\NameParser\Part\Salutation; +use CodeByZach\NameParser\Mapper\LastnameMapper; use CodeByZach\NameParser\Part\Firstname; use CodeByZach\NameParser\Part\Lastname; use CodeByZach\NameParser\Part\LastnamePrefix; +use CodeByZach\NameParser\Part\Salutation; -class LastnameMapperTest extends AbstractMapperTest +class LastnameMapperTest extends AbstractMapperTestCase { /** * @return array */ - public function provider() + public static function provider() { return [ [ diff --git a/tests/Mapper/MiddlenameMapperTest.php b/tests/Mapper/MiddlenameMapperTest.php index 2ba5eb6..d67d664 100644 --- a/tests/Mapper/MiddlenameMapperTest.php +++ b/tests/Mapper/MiddlenameMapperTest.php @@ -2,17 +2,18 @@ namespace Tests\CodeByZach\NameParser\Mapper; -use CodeByZach\NameParser\Part\Salutation; +use CodeByZach\NameParser\Mapper\MiddlenameMapper; use CodeByZach\NameParser\Part\Firstname; -use CodeByZach\NameParser\Part\Middlename; use CodeByZach\NameParser\Part\Lastname; +use CodeByZach\NameParser\Part\Middlename; +use CodeByZach\NameParser\Part\Salutation; -class MiddlenameMapperTest extends AbstractMapperTest +class MiddlenameMapperTest extends AbstractMapperTestCase { /** * @return array */ - public function provider() + public static function provider() { return [ [ diff --git a/tests/Mapper/NicknameMapperTest.php b/tests/Mapper/NicknameMapperTest.php index b2d6138..5ee9f96 100644 --- a/tests/Mapper/NicknameMapperTest.php +++ b/tests/Mapper/NicknameMapperTest.php @@ -2,15 +2,16 @@ namespace Tests\CodeByZach\NameParser\Mapper; -use CodeByZach\NameParser\Part\Salutation; +use CodeByZach\NameParser\Mapper\NicknameMapper; use CodeByZach\NameParser\Part\Nickname; +use CodeByZach\NameParser\Part\Salutation; -class NicknameMapperTest extends AbstractMapperTest +class NicknameMapperTest extends AbstractMapperTestCase { /** * @return array */ - public function provider() + public static function provider() { return [ [ diff --git a/tests/Mapper/SalutationMapperTest.php b/tests/Mapper/SalutationMapperTest.php index a89f6e2..b169803 100644 --- a/tests/Mapper/SalutationMapperTest.php +++ b/tests/Mapper/SalutationMapperTest.php @@ -3,16 +3,17 @@ namespace Tests\CodeByZach\NameParser\Mapper; use CodeByZach\NameParser\Language\English; -use CodeByZach\NameParser\Part\Salutation; +use CodeByZach\NameParser\Mapper\SalutationMapper; use CodeByZach\NameParser\Part\Firstname; use CodeByZach\NameParser\Part\Lastname; +use CodeByZach\NameParser\Part\Salutation; -class SalutationMapperTest extends AbstractMapperTest +class SalutationMapperTest extends AbstractMapperTestCase { /** * @return array */ - public function provider() + public static function provider() { return [ [ diff --git a/tests/Mapper/SuffixMapperTest.php b/tests/Mapper/SuffixMapperTest.php index f6b4596..3361185 100644 --- a/tests/Mapper/SuffixMapperTest.php +++ b/tests/Mapper/SuffixMapperTest.php @@ -3,16 +3,17 @@ namespace Tests\CodeByZach\NameParser\Mapper; use CodeByZach\NameParser\Language\English; -use CodeByZach\NameParser\Part\Lastname; +use CodeByZach\NameParser\Mapper\SuffixMapper; use CodeByZach\NameParser\Part\Firstname; +use CodeByZach\NameParser\Part\Lastname; use CodeByZach\NameParser\Part\Suffix; -class SuffixMapperTest extends AbstractMapperTest +class SuffixMapperTest extends AbstractMapperTestCase { /** * @return array */ - public function provider() + public static function provider() { return [ [ @@ -28,10 +29,10 @@ public function provider() 'Blueberg', new Suffix('PhD'), ], - [ + 'arguments' => [ 'matchSinglePart' => false, 'reservedParts' => 2, - ] + ], ], [ 'input' => [ @@ -44,10 +45,10 @@ public function provider() 'Alfred', new Suffix('III'), ], - [ + 'arguments' => [ 'matchSinglePart' => false, 'reservedParts' => 2, - ] + ], ], [ 'input' => [ @@ -60,10 +61,10 @@ public function provider() new Lastname('Smith'), new Suffix('Senior'), ], - [ + 'arguments' => [ 'matchSinglePart' => false, 'reservedParts' => 2, - ] + ], ], [ 'input' => [ @@ -76,10 +77,10 @@ public function provider() new Firstname('James'), 'Norrington', ], - [ + 'arguments' => [ 'matchSinglePart' => false, 'reservedParts' => 2, - ] + ], ], [ 'input' => [ @@ -92,10 +93,10 @@ public function provider() new Firstname('James'), new Lastname('Norrington'), ], - [ + 'arguments' => [ 'matchSinglePart' => false, 'reservedParts' => 2, - ] + ], ], [ 'input' => [ @@ -108,10 +109,10 @@ public function provider() 'Norrington', new Suffix('Senior'), ], - [ + 'arguments' => [ false, 2, - ] + ], ], [ 'input' => [ @@ -122,10 +123,10 @@ public function provider() 'Norrington', 'Senior', ], - [ + 'arguments' => [ false, 2, - ] + ], ], [ 'input' => [ @@ -136,10 +137,10 @@ public function provider() new Lastname('Norrington'), new Suffix('Senior'), ], - [ + 'arguments' => [ false, 1, - ] + ], ], [ 'input' => [ @@ -148,9 +149,9 @@ public function provider() 'expectation' => [ new Suffix('Senior'), ], - [ + 'arguments' => [ true, - ] + ], ], ]; } diff --git a/tests/NameTest.php b/tests/NameTest.php index 9270ea1..7a87261 100644 --- a/tests/NameTest.php +++ b/tests/NameTest.php @@ -2,7 +2,8 @@ namespace Tests\CodeByZach\NameParser; -use PHPUnit\Framework\TestCase; +use CodeByZach\NameParser\Name; +use CodeByZach\NameParser\Parser; use CodeByZach\NameParser\Part\Firstname; use CodeByZach\NameParser\Part\Initial; use CodeByZach\NameParser\Part\Lastname; @@ -11,6 +12,7 @@ use CodeByZach\NameParser\Part\Nickname; use CodeByZach\NameParser\Part\Salutation; use CodeByZach\NameParser\Part\Suffix; +use PHPUnit\Framework\TestCase; class NameTest extends TestCase { diff --git a/tests/ParserTest.php b/tests/ParserTest.php index ccc1383..ee9c74b 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -2,16 +2,19 @@ namespace Tests\CodeByZach\NameParser; -use PHPUnit\Framework\TestCase; use CodeByZach\NameParser\Language\English; use CodeByZach\NameParser\Language\German; +use CodeByZach\NameParser\Name; +use CodeByZach\NameParser\Parser; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\TestCase; class ParserTest extends TestCase { /** * @return array */ - public function provider() + public static function provider() { return [ [ @@ -563,12 +566,7 @@ public function provider() ]; } - /** - * @dataProvider provider - * - * @param $input - * @param $expectation - */ + #[DataProvider('provider')] public function testParse($input, $expectation) { $parser = new Parser(); diff --git a/tests/Part/AbstractPartTest.php b/tests/Part/AbstractPartTest.php index 79bf3f0..bd6bd6e 100644 --- a/tests/Part/AbstractPartTest.php +++ b/tests/Part/AbstractPartTest.php @@ -2,28 +2,23 @@ namespace Tests\CodeByZach\NameParser\Part; +use CodeByZach\NameParser\Part\AbstractPart; use PHPUnit\Framework\TestCase; class AbstractPartTest extends TestCase { - /** - * make sure the placeholder normalize() method returns the original value - */ public function testNormalize() { - $part = $this->getMockForAbstractClass(AbstractPart::class, ['abc']); + $part = new class('abc') extends AbstractPart {}; $this->assertEquals('abc', $part->normalize()); } - /** - * make sure we unwrap any parts during setValue() calls - */ public function testSetValueUnwraps() { - $part = $this->getMockForAbstractClass(AbstractPart::class, ['abc']); + $part = new class('abc') extends AbstractPart {}; $this->assertEquals('abc', $part->getValue()); - $part = $this->getMockForAbstractClass(AbstractPart::class, [$part]); - $this->assertEquals('abc', $part->getValue()); + $wrapped = new class($part) extends AbstractPart {}; + $this->assertEquals('abc', $wrapped->getValue()); } } diff --git a/tests/Part/NormalisationTest.php b/tests/Part/NormalisationTest.php index fa996d6..d9c3263 100644 --- a/tests/Part/NormalisationTest.php +++ b/tests/Part/NormalisationTest.php @@ -2,6 +2,8 @@ namespace Tests\CodeByZach\NameParser\Part; +use CodeByZach\NameParser\Part\Firstname; +use CodeByZach\NameParser\Part\Lastname; use phpmock\phpunit\PHPMock; use PHPUnit\Framework\TestCase; @@ -9,6 +11,11 @@ class NormalisationTest extends TestCase { use PHPMock; + public static function setUpBeforeClass(): void + { + self::defineFunctionMock('CodeByZach\NameParser\Part', 'function_exists'); + } + /** * make sure we test both with and without mb_string support */ diff --git a/tests/bootstrap.php b/tests/bootstrap.php index a57e174..3a9f8b8 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,7 +1,3 @@ Date: Sun, 10 May 2026 17:03:33 -0400 Subject: [PATCH 07/14] Phase 3b: switch to PHP-CS-Fixer + PHPStan 2.x; bump to PHP 8.3 + PHPUnit 12 PHP / Composer: - Bump php floor from ^8.2 to ^8.3 (allows PHPUnit 12; constraint already covers 8.3, 8.4, 8.5) - Replace laravel/pint ^1.18 with friendsofphp/php-cs-fixer ^3.64 (framework-neutral tooling for a framework-neutral library; matches the PHPUnit-not-Pest decision) - Bump phpunit/phpunit ^11.0 -> ^12.0 - Bump phpstan/phpstan ^1.12 -> ^2.1 (50-70% less memory, level 10 available, better PHP 8.4/8.5 support) - .tool-versions: php 8.4 -> php 8.3 to match the project floor and silence the PHP-CS-Fixer 'running on newer PHP than minimum' warning - Composer scripts: lint/lint:fix now invoke php-cs-fixer Static analysis: - Add phpstan.neon.dist (level 5; covers src/ and tests/) - Add phpstan-baseline.neon (currently empty - codebase passes level 5) - Fix one real bug PHPStan 2.x caught: preg_quote() in Parser::normalize was missing the '/' delimiter argument, so user-provided whitespace containing '/' would corrupt the regex - Tighten three @return PHPDoc inconsistencies that PHPStan flagged (FirstnameMapper, MiddlenameMapper, AbstractPart) Code style: - Add .php-cs-fixer.dist.php using @PER-CS2.0 + @PHP83Migration rulesets (PER-CS is the modern PSR-12 successor; framework-neutral) - Apply formatter to whole codebase: alphabetized imports, trailing commas in multi-line, single quotes, short array syntax, etc. - Restore camelCase test method names (Pint's laravel preset had converted them to snake_case, which is Laravel app convention but not standard PHPUnit) Tooling: - Remove pint.json (replaced by .php-cs-fixer.dist.php) - .gitignore: add .php-cs-fixer.cache Test suite: 131 tests, 235 assertions, 0 errors/warnings/deprecations on PHP 8.3 / PHPUnit 12.x / PHPStan 2.x. --- .gitignore | 1 + .php-cs-fixer.dist.php | 20 + .tool-versions | 2 +- composer.json | 17 +- composer.lock | 4505 +++++++++++++++++++------ phpstan-baseline.neon | 2 + phpstan.neon.dist | 10 + src/Language/English.php | 8 +- src/Language/German.php | 8 +- src/Mapper/AbstractMapper.php | 13 +- src/Mapper/FirstnameMapper.php | 21 +- src/Mapper/InitialMapper.php | 14 +- src/Mapper/LastnameMapper.php | 60 +- src/Mapper/MiddlenameMapper.php | 9 +- src/Mapper/NicknameMapper.php | 8 +- src/Mapper/SalutationMapper.php | 17 +- src/Mapper/SuffixMapper.php | 19 +- src/Name.php | 52 +- src/Parser.php | 61 +- src/Part/AbstractPart.php | 16 +- src/Part/Firstname.php | 4 +- src/Part/GivenNamePart.php | 4 +- src/Part/Initial.php | 2 - src/Part/Lastname.php | 4 +- src/Part/LastnamePrefix.php | 2 - src/Part/Middlename.php | 4 +- src/Part/NamePart.php | 2 - src/Part/Nickname.php | 2 - src/Part/PreNormalizedPart.php | 2 - src/Part/Salutation.php | 5 +- src/Part/Suffix.php | 5 +- tests/GermanParserTest.php | 10 +- tests/Mapper/FirstnameMapperTest.php | 4 +- tests/Mapper/InitialMapperTest.php | 21 +- tests/Mapper/LastnameMapperTest.php | 8 +- tests/Mapper/MiddlenameMapperTest.php | 3 +- tests/Mapper/NicknameMapperTest.php | 2 +- tests/Mapper/SalutationMapperTest.php | 1 - tests/ParserTest.php | 153 +- tests/Part/AbstractPartTest.php | 6 +- tests/Part/NormalisationTest.php | 2 +- tests/bootstrap.php | 2 +- 42 files changed, 3726 insertions(+), 1385 deletions(-) create mode 100644 .php-cs-fixer.dist.php create mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon.dist diff --git a/.gitignore b/.gitignore index ecfa7a7..455f54e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /vendor/ /tests/coverage /.phpunit.cache/ +/.php-cs-fixer.cache phpunit.xml diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..7e70781 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,20 @@ +in([__DIR__.'/src', __DIR__.'/tests']); + +return (new PhpCsFixer\Config()) + ->setRiskyAllowed(true) + ->setRules([ + '@PER-CS2.0' => true, + '@PHP83Migration' => true, + 'ordered_imports' => ['sort_algorithm' => 'alpha'], + 'no_unused_imports' => true, + 'single_quote' => true, + 'trailing_comma_in_multiline' => true, + 'array_syntax' => ['syntax' => 'short'], + 'blank_line_after_namespace' => true, + 'no_extra_blank_lines' => true, + ]) + ->setFinder($finder) + ->setCacheFile(__DIR__.'/.php-cs-fixer.cache'); diff --git a/.tool-versions b/.tool-versions index de9d6ca..7d27ae4 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -php 8.4 +php 8.3 diff --git a/composer.json b/composer.json index a57af0f..08de575 100644 --- a/composer.json +++ b/composer.json @@ -14,14 +14,14 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "ext-mbstring": "*" }, "require-dev": { - "laravel/pint": "^1.18", + "friendsofphp/php-cs-fixer": "^3.64", "php-mock/php-mock-phpunit": "^2.15", - "phpstan/phpstan": "^1.12", - "phpunit/phpunit": "^11.0" + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^12.0" }, "autoload": { "psr-4": { @@ -35,11 +35,14 @@ }, "scripts": { "analyse": "phpstan analyse", - "lint": "pint --test", - "lint:fix": "pint", + "lint": "php-cs-fixer fix --dry-run --diff", + "lint:fix": "php-cs-fixer fix", "test": "phpunit" }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "php-http/discovery": true + } } } diff --git a/composer.lock b/composer.lock index b51a2c4..eed95f9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,49 +4,35 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "64efbb9a09b6155c57bb901ef9275c87", + "content-hash": "6a14cbf35c6a3a4584f054c1e8a13601", "packages": [], "packages-dev": [ { - "name": "laravel/pint", - "version": "v1.29.1", + "name": "clue/ndjson-react", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/laravel/pint.git", - "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80" + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/0770e9b7fafd50d4586881d456d6eb41c9247a80", - "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", "shasum": "" }, "require": { - "ext-json": "*", - "ext-mbstring": "*", - "ext-tokenizer": "*", - "ext-xml": "*", - "php": "^8.2.0" + "php": ">=5.3", + "react/stream": "^1.2" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.95.1", - "illuminate/view": "^12.56.0", - "larastan/larastan": "^3.9.6", - "laravel-zero/framework": "^12.1.0", - "mockery/mockery": "^1.6.12", - "nunomaduro/termwind": "^2.4.0", - "pestphp/pest": "^3.8.6", - "shipfastlabs/agent-detector": "^1.1.3" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" }, - "bin": [ - "builds/pint" - ], - "type": "project", + "type": "library", "autoload": { "psr-4": { - "App\\": "app/", - "Database\\Seeders\\": "database/seeders/", - "Database\\Factories\\": "database/factories/" + "Clue\\React\\NDJson\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -55,562 +41,2872 @@ ], "authors": [ { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" + "name": "Christian Lück", + "email": "christian@clue.engineering" } ], - "description": "An opinionated code formatter for PHP.", - "homepage": "https://laravel.com", + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", "keywords": [ - "dev", - "format", - "formatter", - "lint", - "linter", - "php" + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" ], "support": { - "issues": "https://github.com/laravel/pint/issues", - "source": "https://github.com/laravel/pint" + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" }, - "time": "2026-04-20T15:26:14+00:00" + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-12-23T10:58:28+00:00" }, { - "name": "myclabs/deep-copy", - "version": "1.13.4", + "name": "composer/pcre", + "version": "3.3.2", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", - "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^7.4 || ^8.0" }, "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3 <3.2.2" + "phpstan/phpstan": "<1.11.10" }, "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpspec/prophecy": "^1.10", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" }, "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], "psr-4": { - "DeepCopy\\": "src/DeepCopy/" + "Composer\\Pcre\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "PCRE", + "preg", + "regex", + "regular expression" ], "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" }, "funding": [ { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], - "time": "2025-08-01T08:46:24+00:00" + "time": "2024-11-12T16:29:46+00:00" }, { - "name": "nikic/php-parser", - "version": "v5.7.0", + "name": "composer/semver", + "version": "3.4.4", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + "url": "https://github.com/composer/semver.git", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" + "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^9.0" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, - "bin": [ - "bin/php-parse" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "5.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { "psr-4": { - "PhpParser\\": "lib/PhpParser" + "Composer\\Semver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], - "description": "A PHP parser written in PHP", + "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ - "parser", - "php" + "semantic", + "semver", + "validation", + "versioning" ], "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.4" }, - "time": "2025-12-06T11:56:16+00:00" + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2025-08-20T19:15:30+00:00" }, { - "name": "phar-io/manifest", - "version": "2.0.4", + "name": "composer/xdebug-handler", + "version": "3.0.5", "source": { "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "54750ef60c58e43759730615a392c31c80e23176" + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", - "reference": "54750ef60c58e43759730615a392c31c80e23176", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, + "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" } ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.4" + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" }, "funding": [ { - "url": "https://github.com/theseer", + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" } ], - "time": "2024-03-03T12:33:53+00:00" + "time": "2024-05-06T16:37:16+00:00" }, { - "name": "phar-io/version", - "version": "3.2.1", + "name": "ergebnis/agent-detector", + "version": "1.2.0", "source": { "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + "url": "https://github.com/ergebnis/agent-detector.git", + "reference": "e211f17928c8b95a51e06040792d57f5462fb271" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "url": "https://api.github.com/repos/ergebnis/agent-detector/zipball/e211f17928c8b95a51e06040792d57f5462fb271", + "reference": "e211f17928c8b95a51e06040792d57f5462fb271", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.51.0", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.60.2", + "ergebnis/phpstan-rules": "^2.13.1", + "ergebnis/phpunit-slow-test-detector": "^2.24.0", + "ergebnis/rector-rules": "^1.18.1", + "fakerphp/faker": "^1.24.1", + "infection/infection": "^0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.54", + "phpstan/phpstan-deprecation-rules": "^2.0.4", + "phpstan/phpstan-phpunit": "^2.0.16", + "phpstan/phpstan-strict-rules": "^2.0.10", + "phpunit/phpunit": "^9.6.34", + "rector/rector": "^2.4.2" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + }, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" + } + }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Ergebnis\\AgentDetector\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], - "description": "Library for handling version information and constraints", + "description": "Provides a detector for detecting the presence of an agent.", + "homepage": "https://github.com/ergebnis/agent-detector", "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" + "issues": "https://github.com/ergebnis/agent-detector/issues", + "security": "https://github.com/ergebnis/agent-detector/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/agent-detector" }, - "time": "2022-02-21T01:04:05+00:00" + "time": "2026-05-07T08:19:07+00:00" }, { - "name": "php-mock/php-mock", - "version": "2.7.0", + "name": "evenement/evenement", + "version": "v3.0.2", "source": { "type": "git", - "url": "https://github.com/php-mock/php-mock.git", - "reference": "b59734f19765296bb0311942850d02288a224890" + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-mock/php-mock/zipball/b59734f19765296bb0311942850d02288a224890", - "reference": "b59734f19765296bb0311942850d02288a224890", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0 || ^8.0", - "phpunit/php-text-template": "^1 || ^2 || ^3 || ^4 || ^5 || ^6" - }, - "replace": { - "malkusch/php-mock": "*" + "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0", - "squizlabs/php_codesniffer": "^3.8" - }, - "suggest": { - "php-mock/php-mock-phpunit": "Allows integration into PHPUnit testcase with the trait PHPMock." + "phpunit/phpunit": "^9 || ^6" }, "type": "library", "autoload": { - "files": [ - "autoload.php" - ], "psr-4": { - "phpmock\\": [ - "classes/", - "tests/" - ] + "Evenement\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "WTFPL" + "MIT" ], "authors": [ { - "name": "Markus Malkusch", - "email": "markus@malkusch.de", - "homepage": "http://markus.malkusch.de", - "role": "Developer" + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" } ], - "description": "PHP-Mock can mock built-in PHP functions (e.g. time()). PHP-Mock relies on PHP's namespace fallback policy. No further extension is needed.", - "homepage": "https://github.com/php-mock/php-mock", + "description": "Événement is a very simple event dispatching library for PHP", "keywords": [ - "BDD", - "TDD", - "function", - "mock", - "stub", - "test", - "test double", - "testing" + "event-dispatcher", + "event-emitter" ], "support": { - "issues": "https://github.com/php-mock/php-mock/issues", - "source": "https://github.com/php-mock/php-mock/tree/2.7.0" + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" }, - "funding": [ - { - "url": "https://github.com/michalbundyra", - "type": "github" - } - ], - "time": "2026-02-06T07:39:37+00:00" + "time": "2023-08-08T05:53:35+00:00" }, { - "name": "php-mock/php-mock-integration", - "version": "3.1.0", + "name": "fidry/cpu-core-counter", + "version": "1.3.0", "source": { "type": "git", - "url": "https://github.com/php-mock/php-mock-integration.git", - "reference": "cbbf39705ec13dece5b04133cef4e2fd3137a345" + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-mock/php-mock-integration/zipball/cbbf39705ec13dece5b04133cef4e2fd3137a345", - "reference": "cbbf39705ec13dece5b04133cef4e2fd3137a345", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", "shasum": "" }, "require": { - "php": ">=5.6", - "php-mock/php-mock": "^2.5", - "phpunit/php-text-template": "^1 || ^2 || ^3 || ^4 || ^5 || ^6" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^5.7.27 || ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || ^13" + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" }, "type": "library", "autoload": { "psr-4": { - "phpmock\\integration\\": "classes/" + "Fidry\\CpuCoreCounter\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "WTFPL" + "MIT" ], "authors": [ { - "name": "Markus Malkusch", - "email": "markus@malkusch.de", - "homepage": "http://markus.malkusch.de", + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2025-08-14T07:29:31+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.95.1", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "a9727678fbd12997f1d9de8f4a37824ed9df1065" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a9727678fbd12997f1d9de8f4a37824ed9df1065", + "reference": "a9727678fbd12997f1d9de8f4a37824ed9df1065", + "shasum": "" + }, + "require": { + "clue/ndjson-react": "^1.3", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.5", + "ergebnis/agent-detector": "^1.1.1", + "ext-filter": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.3", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.6", + "react/event-loop": "^1.5", + "react/socket": "^1.16", + "react/stream": "^1.4", + "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0 || ^8.0", + "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.33", + "symfony/polyfill-php80": "^1.33", + "symfony/polyfill-php81": "^1.33", + "symfony/polyfill-php84": "^1.33", + "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2 || ^8.0", + "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3.1 || ^2.8.0", + "infection/infection": "^0.32.6", + "justinrainbow/json-schema": "^6.8.0", + "keradus/cli-executor": "^2.3", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.9.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.8", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.8", + "phpunit/phpunit": "^9.6.34 || ^10.5.63 || ^11.5.55", + "symfony/polyfill-php85": "^1.33", + "symfony/var-dumper": "^5.4.48 || ^6.4.32 || ^7.4.4 || ^8.0.8", + "symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0.8" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/**/Internal/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.95.1" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2026-04-12T17:00:09+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.7.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + }, + "time": "2025-12-06T11:56:16+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", "role": "Developer" } ], - "description": "Integration package for PHP-Mock", - "homepage": "https://github.com/php-mock/php-mock-integration", + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "php-mock/php-mock", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/php-mock/php-mock.git", + "reference": "b59734f19765296bb0311942850d02288a224890" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-mock/php-mock/zipball/b59734f19765296bb0311942850d02288a224890", + "reference": "b59734f19765296bb0311942850d02288a224890", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0 || ^8.0", + "phpunit/php-text-template": "^1 || ^2 || ^3 || ^4 || ^5 || ^6" + }, + "replace": { + "malkusch/php-mock": "*" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0", + "squizlabs/php_codesniffer": "^3.8" + }, + "suggest": { + "php-mock/php-mock-phpunit": "Allows integration into PHPUnit testcase with the trait PHPMock." + }, + "type": "library", + "autoload": { + "files": [ + "autoload.php" + ], + "psr-4": { + "phpmock\\": [ + "classes/", + "tests/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "WTFPL" + ], + "authors": [ + { + "name": "Markus Malkusch", + "email": "markus@malkusch.de", + "homepage": "http://markus.malkusch.de", + "role": "Developer" + } + ], + "description": "PHP-Mock can mock built-in PHP functions (e.g. time()). PHP-Mock relies on PHP's namespace fallback policy. No further extension is needed.", + "homepage": "https://github.com/php-mock/php-mock", + "keywords": [ + "BDD", + "TDD", + "function", + "mock", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "issues": "https://github.com/php-mock/php-mock/issues", + "source": "https://github.com/php-mock/php-mock/tree/2.7.0" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } + ], + "time": "2026-02-06T07:39:37+00:00" + }, + { + "name": "php-mock/php-mock-integration", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-mock/php-mock-integration.git", + "reference": "cbbf39705ec13dece5b04133cef4e2fd3137a345" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-mock/php-mock-integration/zipball/cbbf39705ec13dece5b04133cef4e2fd3137a345", + "reference": "cbbf39705ec13dece5b04133cef4e2fd3137a345", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "php-mock/php-mock": "^2.5", + "phpunit/php-text-template": "^1 || ^2 || ^3 || ^4 || ^5 || ^6" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.27 || ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || ^13" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpmock\\integration\\": "classes/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "WTFPL" + ], + "authors": [ + { + "name": "Markus Malkusch", + "email": "markus@malkusch.de", + "homepage": "http://markus.malkusch.de", + "role": "Developer" + } + ], + "description": "Integration package for PHP-Mock", + "homepage": "https://github.com/php-mock/php-mock-integration", + "keywords": [ + "BDD", + "TDD", + "function", + "mock", + "stub", + "test", + "test double" + ], + "support": { + "issues": "https://github.com/php-mock/php-mock-integration/issues", + "source": "https://github.com/php-mock/php-mock-integration/tree/3.1.0" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } + ], + "time": "2026-02-06T07:44:43+00:00" + }, + { + "name": "php-mock/php-mock-phpunit", + "version": "2.15.0", + "source": { + "type": "git", + "url": "https://github.com/php-mock/php-mock-phpunit.git", + "reference": "701df15b183f25af663af134eb71353cd838b955" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-mock/php-mock-phpunit/zipball/701df15b183f25af663af134eb71353cd838b955", + "reference": "701df15b183f25af663af134eb71353cd838b955", + "shasum": "" + }, + "require": { + "php": ">=7", + "php-mock/php-mock-integration": "^3.0", + "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17 || ^11 || ^12.0.9 || ^13" + }, + "require-dev": { + "mockery/mockery": "^1.3.6" + }, + "type": "library", + "autoload": { + "files": [ + "autoload.php" + ], + "psr-4": { + "phpmock\\phpunit\\": "classes/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "WTFPL" + ], + "authors": [ + { + "name": "Markus Malkusch", + "email": "markus@malkusch.de", + "homepage": "http://markus.malkusch.de", + "role": "Developer" + } + ], + "description": "Mock built-in PHP functions (e.g. time()) with PHPUnit. This package relies on PHP's namespace fallback policy. No further extension is needed.", + "homepage": "https://github.com/php-mock/php-mock-phpunit", + "keywords": [ + "BDD", + "TDD", + "function", + "mock", + "phpunit", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "issues": "https://github.com/php-mock/php-mock-phpunit/issues", + "source": "https://github.com/php-mock/php-mock-phpunit/tree/2.15.0" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } + ], + "time": "2026-02-06T09:12:10+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.1.54", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8be50c3992107dc837b17da4d140fbbdf9a5c5bd", + "reference": "8be50c3992107dc837b17da4d140fbbdf9a5c5bd", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2026-04-29T13:31:09+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "12.5.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "876099a072646c7745f673d7aeab5382c4439691" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/876099a072646c7745f673d7aeab5382c4439691", + "reference": "876099a072646c7745f673d7aeab5382c4439691", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.7.0", + "php": ">=8.3", + "phpunit/php-text-template": "^5.0", + "sebastian/complexity": "^5.0", + "sebastian/environment": "^8.0.3", + "sebastian/lines-of-code": "^4.0", + "sebastian/version": "^6.0", + "theseer/tokenizer": "^2.0.1" + }, + "require-dev": { + "phpunit/phpunit": "^12.5.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "12.5.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" + } + ], + "time": "2026-04-15T08:23:17+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5", + "reference": "3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator", + "type": "tidelift" + } + ], + "time": "2026-02-02T14:04:18+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^12.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:58:58+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:59:16+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "8.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "8.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/8.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:59:38+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "12.5.24", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "d75dd30597caa80e72fad2ef7904601a30ef1046" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d75dd30597caa80e72fad2ef7904601a30ef1046", + "reference": "d75dd30597caa80e72fad2ef7904601a30ef1046", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.3", + "phpunit/php-code-coverage": "^12.5.6", + "phpunit/php-file-iterator": "^6.0.1", + "phpunit/php-invoker": "^6.0.0", + "phpunit/php-text-template": "^5.0.0", + "phpunit/php-timer": "^8.0.0", + "sebastian/cli-parser": "^4.2.0", + "sebastian/comparator": "^7.1.6", + "sebastian/diff": "^7.0.0", + "sebastian/environment": "^8.1.0", + "sebastian/exporter": "^7.0.2", + "sebastian/global-state": "^8.0.2", + "sebastian/object-enumerator": "^7.0.0", + "sebastian/recursion-context": "^7.0.1", + "sebastian/type": "^6.0.3", + "sebastian/version": "^6.0.0", + "staabm/side-effects-detector": "^1.0.5" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "12.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.24" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsoring.html", + "type": "other" + } + ], + "time": "2026-05-01T04:21:04+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.7", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/970f0e71945556422ee4570ccbabaedc3cf04ad3", + "reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.7" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-12-23T15:25:20+00:00" + }, + { + "name": "react/dns", + "version": "v1.14.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/7562c05391f42701c1fccf189c8225fece1cd7c3", + "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.14.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-11-18T19:34:28+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/ba276bda6083df7e0050fd9b33f66ad7a4ac747a", + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.6.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-11-17T20:46:25+00:00" + }, + { + "name": "react/promise", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.12.28 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-08-19T18:57:03+00:00" + }, + { + "name": "react/socket", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/ef5b17b81f6f60504c539313f94f2d826c5faa08", + "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.17.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-11-19T20:47:34+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/90f41072d220e5c40df6e8635f5dafba2d9d4d04", + "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/cli-parser", + "type": "tidelift" + } + ], + "time": "2025-09-14T09:36:45+00:00" + }, + { + "name": "sebastian/comparator", + "version": "7.1.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "c769009dee98f494e0edc3fd4f4087501688f11e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c769009dee98f494e0edc3fd4f4087501688f11e", + "reference": "c769009dee98f494e0edc3fd4f4087501688f11e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.3", + "sebastian/diff": "^7.0", + "sebastian/exporter": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^12.2" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/7.1.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2026-04-14T08:23:15+00:00" + }, + { + "name": "sebastian/complexity", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:55:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0", + "symfony/process": "^7.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:55:46+00:00" + }, + { + "name": "sebastian/environment", + "version": "8.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "b121608b28a13f721e76ffbbd386d08eff58f3f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/b121608b28a13f721e76ffbbd386d08eff58f3f6", + "reference": "b121608b28a13f721e76ffbbd386d08eff58f3f6", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "8.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/8.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" + } + ], + "time": "2026-04-15T12:13:01+00:00" + }, + { + "name": "sebastian/exporter", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "016951ae10980765e4e7aee491eb288c64e505b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/016951ae10980765e4e7aee491eb288c64e505b7", + "reference": "016951ae10980765e4e7aee491eb288c64e505b7", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.3", + "sebastian/recursion-context": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:16:11+00:00" + }, + { + "name": "sebastian/global-state", + "version": "8.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "ef1377171613d09edd25b7816f05be8313f9115d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ef1377171613d09edd25b7816f05be8313f9115d", + "reference": "ef1377171613d09edd25b7816f05be8313f9115d", + "shasum": "" + }, + "require": { + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "8.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ - "BDD", - "TDD", - "function", - "mock", - "stub", - "test", - "test double" + "global state" ], "support": { - "issues": "https://github.com/php-mock/php-mock-integration/issues", - "source": "https://github.com/php-mock/php-mock-integration/tree/3.1.0" + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.2" }, "funding": [ { - "url": "https://github.com/michalbundyra", + "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state", + "type": "tidelift" } ], - "time": "2026-02-06T07:44:43+00:00" + "time": "2025-08-29T11:29:25+00:00" }, { - "name": "php-mock/php-mock-phpunit", - "version": "2.15.0", + "name": "sebastian/lines-of-code", + "version": "4.0.0", "source": { "type": "git", - "url": "https://github.com/php-mock/php-mock-phpunit.git", - "reference": "701df15b183f25af663af134eb71353cd838b955" + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-mock/php-mock-phpunit/zipball/701df15b183f25af663af134eb71353cd838b955", - "reference": "701df15b183f25af663af134eb71353cd838b955", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f", + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f", "shasum": "" }, "require": { - "php": ">=7", - "php-mock/php-mock-integration": "^3.0", - "phpunit/phpunit": "^6 || ^7 || ^8 || ^9 || ^10.0.17 || ^11 || ^12.0.9 || ^13" + "nikic/php-parser": "^5.0", + "php": ">=8.3" }, "require-dev": { - "mockery/mockery": "^1.3.6" + "phpunit/phpunit": "^12.0" }, "type": "library", - "autoload": { - "files": [ - "autoload.php" - ], - "psr-4": { - "phpmock\\phpunit\\": "classes/" + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "WTFPL" + "BSD-3-Clause" ], "authors": [ { - "name": "Markus Malkusch", - "email": "markus@malkusch.de", - "homepage": "http://markus.malkusch.de", - "role": "Developer" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Mock built-in PHP functions (e.g. time()) with PHPUnit. This package relies on PHP's namespace fallback policy. No further extension is needed.", - "homepage": "https://github.com/php-mock/php-mock-phpunit", - "keywords": [ - "BDD", - "TDD", - "function", - "mock", - "phpunit", - "stub", - "test", - "test double", - "testing" - ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { - "issues": "https://github.com/php-mock/php-mock-phpunit/issues", - "source": "https://github.com/php-mock/php-mock-phpunit/tree/2.15.0" + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.0" }, "funding": [ { - "url": "https://github.com/michalbundyra", + "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2026-02-06T09:12:10+00:00" + "time": "2025-02-07T04:57:28+00:00" }, { - "name": "phpstan/phpstan", - "version": "1.12.33", + "name": "sebastian/object-enumerator", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894" + }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/37982d6fc7cbb746dda7773530cda557cdf119e1", - "reference": "37982d6fc7cbb746dda7773530cda557cdf119e1", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" }, - "conflict": { - "phpstan/phpstan-shim": "*" + "require-dev": { + "phpunit/phpunit": "^12.0" }, - "bin": [ - "phpstan", - "phpstan.phar" - ], "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, "autoload": { - "files": [ - "bootstrap.php" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], - "description": "PHPStan - PHP Static Analysis Tool", - "keywords": [ - "dev", - "static analysis" + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { - "docs": "https://phpstan.org/user-guide/getting-started", - "forum": "https://github.com/phpstan/phpstan/discussions", - "issues": "https://github.com/phpstan/phpstan/issues", - "security": "https://github.com/phpstan/phpstan/security/policy", - "source": "https://github.com/phpstan/phpstan-src" + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/7.0.0" }, "funding": [ { - "url": "https://github.com/ondrejmirtes", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, + } + ], + "time": "2025-02-07T04:57:48+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ { - "url": "https://github.com/phpstan", + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2026-02-28T20:30:03+00:00" + "time": "2025-02-07T04:58:17+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "11.0.12", + "name": "sebastian/recursion-context", + "version": "7.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2c1ed04922802c15e1de5d7447b4856de949cf56", - "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^5.7.0", - "php": ">=8.2", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-text-template": "^4.0.1", - "sebastian/code-unit-reverse-lookup": "^4.0.1", - "sebastian/complexity": "^4.0.1", - "sebastian/environment": "^7.2.1", - "sebastian/lines-of-code": "^3.0.1", - "sebastian/version": "^5.0.2", - "theseer/tokenizer": "^1.3.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^11.5.46" - }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "11.0.x-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -625,21 +2921,23 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.12" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/7.0.1" }, "funding": [ { @@ -655,36 +2953,36 @@ "type": "thanks_dev" }, { - "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", "type": "tidelift" } ], - "time": "2025-12-24T07:01:01+00:00" + "time": "2025-08-13T04:44:59+00:00" }, { - "name": "phpunit/php-file-iterator", - "version": "5.1.1", + "name": "sebastian/type", + "version": "6.0.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/2f3a64888c814fc235386b7387dd5b5ed92ad903", - "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/e549163b9760b8f71f191651d22acf32d56d6d4d", + "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^11.3" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -703,16 +3001,12 @@ "role": "lead" } ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.1" + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/6.0.3" }, "funding": [ { @@ -728,40 +3022,33 @@ "type": "thanks_dev" }, { - "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator", + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", "type": "tidelift" } ], - "time": "2026-02-02T13:52:54+00:00" + "time": "2025-08-09T06:57:12+00:00" }, { - "name": "phpunit/php-invoker", - "version": "5.0.1", + "name": "sebastian/version", + "version": "6.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^11.0" - }, - "suggest": { - "ext-pcntl": "*" + "php": ">=8.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -780,15 +3067,12 @@ "role": "lead" } ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/6.0.0" }, "funding": [ { @@ -796,1295 +3080,1510 @@ "type": "github" } ], - "time": "2024-07-03T05:07:44+00:00" + "time": "2025-02-07T05:00:38+00:00" }, { - "name": "phpunit/php-text-template", - "version": "4.0.1", + "name": "staabm/side-effects-detector", + "version": "1.0.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", "shasum": "" }, "require": { - "php": ">=8.2" + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, "autoload": { "classmap": [ - "src/" + "lib/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } + "MIT" ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "A static analysis tool to detect side effects in PHP code", "keywords": [ - "template" + "static analysis" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/staabm", "type": "github" } ], - "time": "2024-07-03T05:08:43+00:00" + "time": "2024-10-20T05:08:20+00:00" }, { - "name": "phpunit/php-timer", - "version": "7.0.1", + "name": "symfony/console", + "version": "v7.4.9", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + "url": "https://github.com/symfony/console.git", + "reference": "d7d2b64a45a89d607865927b176fa51c33ddbb58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "url": "https://api.github.com/repos/symfony/console/zipball/d7d2b64a45a89d607865927b176fa51c33ddbb58", + "reference": "d7d2b64a45a89d607865927b176fa51c33ddbb58", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2|^8.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/lock": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", "keywords": [ - "timer" + "cli", + "command-line", + "console", + "terminal" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + "source": "https://github.com/symfony/console/tree/v7.4.9" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T05:09:35+00:00" + "time": "2026-04-22T15:21:55+00:00" }, { - "name": "phpunit/phpunit", - "version": "11.5.55", + "name": "symfony/deprecation-contracts", + "version": "v3.7.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/adc7262fccc12de2b30f12a8aa0b33775d814f00", - "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.4", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", - "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.12", - "phpunit/php-file-iterator": "^5.1.1", - "phpunit/php-invoker": "^5.0.1", - "phpunit/php-text-template": "^4.0.1", - "phpunit/php-timer": "^7.0.1", - "sebastian/cli-parser": "^3.0.2", - "sebastian/code-unit": "^3.0.3", - "sebastian/comparator": "^6.3.3", - "sebastian/diff": "^6.0.2", - "sebastian/environment": "^7.2.1", - "sebastian/exporter": "^6.3.2", - "sebastian/global-state": "^7.0.2", - "sebastian/object-enumerator": "^6.0.1", - "sebastian/recursion-context": "^6.0.3", - "sebastian/type": "^5.1.3", - "sebastian/version": "^5.0.2", - "staabm/side-effects-detector": "^1.0.5" + "php": ">=8.1" }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" - }, - "bin": [ - "phpunit" - ], "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { - "dev-main": "11.5-dev" + "dev-main": "3.7-dev" } }, "autoload": { "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" + "function.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.55" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.0" }, "funding": [ { - "url": "https://phpunit.de/sponsors.html", + "url": "https://symfony.com/sponsor", "type": "custom" }, { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/fabpot", "type": "github" }, { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2026-02-18T12:37:06+00:00" + "time": "2026-04-13T15:52:40+00:00" }, { - "name": "sebastian/cli-parser", - "version": "3.0.2", + "name": "symfony/event-dispatcher", + "version": "v7.4.9", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e4a2e29753c7801f7a8340e066cfa788f3bc8101", + "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0|^8.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.9" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:41:36+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { - "name": "sebastian/code-unit", - "version": "3.0.3", + "name": "symfony/event-dispatcher-contracts", + "version": "v3.7.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", - "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/ccba7060602b7fed0b03c85bf025257f76d9ef32", + "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.5" + "php": ">=8.1", + "psr/event-dispatcher": "^1" }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.7-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2025-03-19T07:56:08+00:00" + "time": "2026-01-05T13:30:16+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "4.0.1", + "name": "symfony/filesystem", + "version": "v7.4.9", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + "url": "https://github.com/symfony/filesystem.git", + "reference": "dcd8f96bcdc0f128ec406c765cc066c6035d1be3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/dcd8f96bcdc0f128ec406c765cc066c6035d1be3", + "reference": "dcd8f96bcdc0f128ec406c765cc066c6035d1be3", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "symfony/process": "^6.4|^7.0|^8.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + "source": "https://github.com/symfony/filesystem/tree/v7.4.9" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:45:54+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { - "name": "sebastian/comparator", - "version": "6.3.3", + "name": "symfony/finder", + "version": "v7.4.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9" + "url": "https://github.com/symfony/finder.git", + "reference": "e0be088d22278583a82da281886e8c3592fbf149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", - "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", + "url": "https://api.github.com/repos/symfony/finder/zipball/e0be088d22278583a82da281886e8c3592fbf149", + "reference": "e0be088d22278583a82da281886e8c3592fbf149", "shasum": "" }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/diff": "^6.0", - "sebastian/exporter": "^6.0" + "require": { + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.4" - }, - "suggest": { - "ext-bcmath": "For comparing BcMath\\Number objects" + "symfony/filesystem": "^6.4|^7.0|^8.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.3-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.3" + "source": "https://github.com/symfony/finder/tree/v7.4.8" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" + "url": "https://github.com/fabpot", + "type": "github" }, { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2026-01-24T09:26:40+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { - "name": "sebastian/complexity", - "version": "4.0.1", + "name": "symfony/options-resolver", + "version": "v7.4.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "2888fcdc4dc2fd5f7c7397be78631e8af12e02b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/2888fcdc4dc2fd5f7c7397be78631e8af12e02b4", + "reference": "2888fcdc4dc2fd5f7c7397be78631e8af12e02b4", "shasum": "" }, "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + "source": "https://github.com/symfony/options-resolver/tree/v7.4.8" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:49:50+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { - "name": "sebastian/diff", - "version": "6.0.2", + "name": "symfony/polyfill-ctype", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=7.2" }, - "require-dev": { - "phpunit/phpunit": "^11.0", - "symfony/process": "^4.2 || ^5" + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "6.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" }, { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" + "compatibility", + "ctype", + "polyfill", + "portable" ], "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:53:05+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { - "name": "sebastian/environment", - "version": "7.2.1", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", - "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e", + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" + "php": ">=7.2" }, "suggest": { - "ext-posix": "*" + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "7.2-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "https://github.com/sebastianbergmann/environment", + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", "keywords": [ - "Xdebug", - "environment", - "hhvm" + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" ], "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.37.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" + "url": "https://github.com/fabpot", + "type": "github" }, { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-05-21T11:55:47+00:00" + "time": "2026-04-26T13:13:48+00:00" }, { - "name": "sebastian/exporter", - "version": "6.3.2", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", - "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/recursion-context": "^6.0" + "php": ">=7.2" }, - "require-dev": { - "phpunit/phpunit": "^11.3" + "suggest": { + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "6.3-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", "keywords": [ - "export", - "exporter" + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" ], "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.37.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" + "url": "https://github.com/fabpot", + "type": "github" }, { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-09-24T06:12:51+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/global-state", - "version": "7.0.2", + "name": "symfony/polyfill-mbstring", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", "shasum": "" }, "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" + "ext-iconv": "*", + "php": ">=7.2" }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^11.0" + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "7.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Snapshotting of global state", - "homepage": "https://www.github.com/sebastianbergmann/global-state", + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", "keywords": [ - "global state" + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" ], "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:57:36+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { - "name": "sebastian/lines-of-code", - "version": "3.0.1", + "name": "symfony/polyfill-php80", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "shasum": "" }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "require": { + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:58:38+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "6.0.1", + "name": "symfony/polyfill-php81", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "6.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.37.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T05:00:13+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/object-reflector", - "version": "4.0.1", + "name": "symfony/polyfill-php84", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "4.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T05:01:32+00:00" + "time": "2026-04-10T18:47:49+00:00" }, { - "name": "sebastian/recursion-context", - "version": "6.0.3", + "name": "symfony/process", + "version": "v7.4.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" + "url": "https://github.com/symfony/process.git", + "reference": "60f19cd3badc8de688421e21e4305eba50f8089a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", - "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "url": "https://api.github.com/repos/symfony/process/zipball/60f19cd3badc8de688421e21e4305eba50f8089a", + "reference": "60f19cd3badc8de688421e21e4305eba50f8089a", "shasum": "" }, "require": { "php": ">=8.2" }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" + "source": "https://github.com/symfony/process/tree/v7.4.8" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" + "url": "https://github.com/fabpot", + "type": "github" }, { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-08-13T04:42:22+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { - "name": "sebastian/type", - "version": "5.1.3", + "name": "symfony/service-contracts", + "version": "v3.7.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449", - "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d25d82433a80eba6aa0e6c24b61d7370d99e444a", + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, - "require-dev": { - "phpunit/phpunit": "^11.3" + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "3.7-dev" } }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.1.3" + "source": "https://github.com/symfony/service-contracts/tree/v3.7.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" + "url": "https://github.com/fabpot", + "type": "github" }, { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/sebastian/type", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-08-09T06:55:48+00:00" + "time": "2026-03-28T09:44:51+00:00" }, { - "name": "sebastian/version", - "version": "5.0.2", + "name": "symfony/stopwatch", + "version": "v7.4.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + "url": "https://github.com/symfony/stopwatch.git", + "reference": "70a852d72fec4d51efb1f48dcd968efcaf5ccb89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/70a852d72fec4d51efb1f48dcd968efcaf5ccb89", + "reference": "70a852d72fec4d51efb1f48dcd968efcaf5ccb89", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" + "source": "https://github.com/symfony/stopwatch/tree/v7.4.8" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-10-09T05:16:32+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { - "name": "staabm/side-effects-detector", - "version": "1.0.5", + "name": "symfony/string", + "version": "v7.4.8", "source": { "type": "git", - "url": "https://github.com/staabm/side-effects-detector.git", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + "url": "https://github.com/symfony/string.git", + "reference": "114ac57257d75df748eda23dd003878080b8e688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "url": "https://api.github.com/repos/symfony/string/zipball/114ac57257d75df748eda23dd003878080b8e688", + "reference": "114ac57257d75df748eda23dd003878080b8e688", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": "^7.4 || ^8.0" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.33", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.6", - "phpunit/phpunit": "^9.6.21", - "symfony/var-dumper": "^5.4.43", - "tomasvotruba/type-coverage": "1.0.0", - "tomasvotruba/unused-public": "1.0.0" + "symfony/emoji": "^7.1|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { - "classmap": [ - "lib/" + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "A static analysis tool to detect side effects in PHP code", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", "keywords": [ - "static analysis" + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" ], "support": { - "issues": "https://github.com/staabm/side-effects-detector/issues", - "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + "source": "https://github.com/symfony/string/tree/v7.4.8" }, "funding": [ { - "url": "https://github.com/staabm", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-10-20T05:08:20+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "theseer/tokenizer", - "version": "1.3.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" + "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", - "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/7989e43bf381af0eac72e4f0ca5bcbfa81658be4", + "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" + "php": "^8.1" }, "type": "library", "autoload": { @@ -2106,7 +4605,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.3.1" + "source": "https://github.com/theseer/tokenizer/tree/2.0.1" }, "funding": [ { @@ -2114,7 +4613,7 @@ "type": "github" } ], - "time": "2025-11-17T20:03:58+00:00" + "time": "2025-12-08T11:19:18+00:00" } ], "aliases": [], @@ -2123,7 +4622,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^8.2", + "php": "^8.3", "ext-mbstring": "*" }, "platform-dev": {}, diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..f51e71c --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,2 @@ +parameters: + ignoreErrors: [] diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..c5c0405 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,10 @@ +parameters: + level: 5 + paths: + - src + - tests + bootstrapFiles: + - tests/bootstrap.php + +includes: + - phpstan-baseline.neon diff --git a/src/Language/English.php b/src/Language/English.php index 1ba818d..9b65aa1 100644 --- a/src/Language/English.php +++ b/src/Language/English.php @@ -6,7 +6,7 @@ class English implements LanguageInterface { - const SUFFIXES = [ + public const SUFFIXES = [ '1st' => '1st', '2nd' => '2nd', '3rd' => '3rd', @@ -54,7 +54,7 @@ class English implements LanguageInterface 'sr' => 'Sr', ]; - const SALUTATIONS = [ + public const SALUTATIONS = [ 'dr' => 'Dr.', 'fr' => 'Fr.', 'hon' => 'Hon.', @@ -73,10 +73,10 @@ class English implements LanguageInterface 'sir' => 'Sir', 'prof' => 'Prof.', 'his honour' => 'His Honour', - 'her honour' => 'Her Honour' + 'her honour' => 'Her Honour', ]; - const LASTNAME_PREFIXES = [ + public const LASTNAME_PREFIXES = [ 'da' => 'da', 'de' => 'de', 'del' => 'del', diff --git a/src/Language/German.php b/src/Language/German.php index 7f390ea..263b26e 100644 --- a/src/Language/German.php +++ b/src/Language/German.php @@ -6,7 +6,7 @@ class German implements LanguageInterface { - const SUFFIXES = [ + public const SUFFIXES = [ '1.' => '1.', '2.' => '2.', '3.' => '3.', @@ -19,14 +19,14 @@ class German implements LanguageInterface 'v' => 'V', ]; - const SALUTATIONS = [ + public const SALUTATIONS = [ 'herr' => 'Herr', 'hr' => 'Herr', 'frau' => 'Frau', - 'fr' => 'Frau' + 'fr' => 'Frau', ]; - const LASTNAME_PREFIXES = [ + public const LASTNAME_PREFIXES = [ 'der' => 'der', 'von' => 'von', ]; diff --git a/src/Mapper/AbstractMapper.php b/src/Mapper/AbstractMapper.php index 01bceec..3cd566a 100644 --- a/src/Mapper/AbstractMapper.php +++ b/src/Mapper/AbstractMapper.php @@ -3,24 +3,19 @@ namespace CodeByZach\NameParser\Mapper; use CodeByZach\NameParser\Part\AbstractPart; -use CodeByZach\NameParser\Part\Nickname; abstract class AbstractMapper { /** * implements the mapping of parts * - * @param array $parts - the name parts + * @param array $parts - the name parts * @return array $parts - the mapped parts */ abstract public function map(array $parts); /** * checks if there are still unmapped parts left before the given position - * - * @param array $parts - * @param $index - * @return bool */ protected function hasUnmappedPartsBefore(array $parts, $index): bool { @@ -29,7 +24,7 @@ protected function hasUnmappedPartsBefore(array $parts, $index): bool break; } - if (!($part instanceof AbstractPart)) { + if (! ($part instanceof AbstractPart)) { return true; } } @@ -38,8 +33,6 @@ protected function hasUnmappedPartsBefore(array $parts, $index): bool } /** - * @param string $type - * @param array $parts * @return int|bool */ protected function findFirstMapped(string $type, array $parts) @@ -58,7 +51,7 @@ protected function findFirstMapped(string $type, array $parts) /** * get the registry lookup key for the given word * - * @param string $word the word + * @param string $word the word * @return string the key */ protected function getKey($word): string diff --git a/src/Mapper/FirstnameMapper.php b/src/Mapper/FirstnameMapper.php index 2e27be0..2d4cbf1 100644 --- a/src/Mapper/FirstnameMapper.php +++ b/src/Mapper/FirstnameMapper.php @@ -4,8 +4,8 @@ use CodeByZach\NameParser\Part\AbstractPart; use CodeByZach\NameParser\Part\Firstname; -use CodeByZach\NameParser\Part\Lastname; use CodeByZach\NameParser\Part\Initial; +use CodeByZach\NameParser\Part\Lastname; use CodeByZach\NameParser\Part\Salutation; class FirstnameMapper extends AbstractMapper @@ -13,7 +13,7 @@ class FirstnameMapper extends AbstractMapper /** * map firstnames in parts array * - * @param array $parts the parts + * @param array $parts the parts * @return array the mapped parts */ public function map(array $parts): array @@ -24,7 +24,7 @@ public function map(array $parts): array $pos = $this->findFirstnamePosition($parts); - if (null !== $pos) { + if ($pos !== null) { $parts[$pos] = new Firstname($parts[$pos]); } @@ -32,8 +32,7 @@ public function map(array $parts): array } /** - * @param $part - * @return Firstname + * @param string|AbstractPart $part */ protected function handleSinglePart($part): AbstractPart { @@ -44,10 +43,6 @@ protected function handleSinglePart($part): AbstractPart return new Firstname($part); } - /** - * @param array $parts - * @return int|null - */ protected function findFirstnamePosition(array $parts): ?int { $pos = null; @@ -62,7 +57,7 @@ protected function findFirstnamePosition(array $parts): ?int break; } - if ($part instanceof Initial && null === $pos) { + if ($part instanceof Initial && $pos === null) { $pos = $k; } @@ -76,15 +71,11 @@ protected function findFirstnamePosition(array $parts): ?int return $pos; } - /** - * @param array $parts - * @return int - */ protected function getStartIndex(array $parts): int { $index = $this->findFirstMapped(Salutation::class, $parts); - if (false === $index) { + if ($index === false) { return 0; } diff --git a/src/Mapper/InitialMapper.php b/src/Mapper/InitialMapper.php index 208f8d3..45f2098 100644 --- a/src/Mapper/InitialMapper.php +++ b/src/Mapper/InitialMapper.php @@ -23,7 +23,7 @@ public function __construct(int $combinedMax = 2, bool $matchLastPart = false) /** * map intials in parts array * - * @param array $parts the name parts + * @param array $parts the name parts * @return array the mapped parts */ public function map(array $parts): array @@ -37,7 +37,7 @@ public function map(array $parts): array continue; } - if (!$this->matchLastPart && $k === $last) { + if (! $this->matchLastPart && $k === $last) { continue; } @@ -45,7 +45,7 @@ public function map(array $parts): array $stripped = str_replace('.', '', $part); $length = strlen($stripped); - if (1 < $length && $length <= $this->combinedMax) { + if ($length > 1 && $length <= $this->combinedMax) { array_splice($parts, $k, 1, str_split($stripped)); $last = count($parts) - 1; $part = $parts[$k]; @@ -60,18 +60,14 @@ public function map(array $parts): array return $parts; } - /** - * @param string $part - * @return bool - */ protected function isInitial(string $part): bool { $length = strlen($part); - if (1 === $length) { + if ($length === 1) { return true; } - return ($length === 2 && substr($part, -1) === '.'); + return $length === 2 && substr($part, -1) === '.'; } } diff --git a/src/Mapper/LastnameMapper.php b/src/Mapper/LastnameMapper.php index dad5e0e..ce30aab 100644 --- a/src/Mapper/LastnameMapper.php +++ b/src/Mapper/LastnameMapper.php @@ -2,7 +2,6 @@ namespace CodeByZach\NameParser\Mapper; -use CodeByZach\NameParser\LanguageInterface; use CodeByZach\NameParser\Part\AbstractPart; use CodeByZach\NameParser\Part\Lastname; use CodeByZach\NameParser\Part\LastnamePrefix; @@ -25,12 +24,12 @@ public function __construct(array $prefixes, bool $matchSinglePart = false) /** * map lastnames in the parts array * - * @param array $parts the name parts + * @param array $parts the name parts * @return array the mapped parts */ public function map(array $parts): array { - if (!$this->matchSinglePart && count($parts) < 2) { + if (! $this->matchSinglePart && count($parts) < 2) { return $parts; } @@ -40,9 +39,6 @@ public function map(array $parts): array /** * we map the parts in reverse order because it makes more * sense to parse for the lastname starting from the end - * - * @param array $parts - * @return array */ protected function mapParts(array $parts): array { @@ -59,6 +55,7 @@ protected function mapParts(array $parts): array if ($this->isFollowedByLastnamePart($parts, $k)) { if ($mapped = $this->mapAsPrefixIfPossible($parts, $k)) { $parts[$k] = $mapped; + continue; } @@ -81,10 +78,6 @@ protected function mapParts(array $parts): array /** * try to map this part as a lastname prefix or as a combined * lastname part containing a prefix - * - * @param array $parts - * @param int $k - * @return Lastname|null */ private function mapAsPrefixIfPossible(array $parts, int $k): ?Lastname { @@ -102,15 +95,12 @@ private function mapAsPrefixIfPossible(array $parts, int $k): ?Lastname /** * check if the given part is a combined lastname part * that ends in a lastname prefix - * - * @param string $part - * @return bool */ private function isCombinedWithPrefix(string $part): bool { $pos = strpos($part, '-'); - if (false === $pos) { + if ($pos === false) { return false; } @@ -119,16 +109,13 @@ private function isCombinedWithPrefix(string $part): bool /** * skip through the parts we want to ignore and return the start index - * - * @param array $parts - * @return int */ protected function skipIgnoredParts(array $parts): int { $k = count($parts); while (--$k >= 0) { - if (!$this->isIgnoredPart($parts[$k])) { + if (! $this->isIgnoredPart($parts[$k])) { break; } } @@ -141,10 +128,6 @@ protected function skipIgnoredParts(array $parts): int * * the assumption is that lastname parts have already been found * but we want to see if we should add more parts - * - * @param array $parts - * @param int $k - * @return bool */ protected function shouldStopMapping(array $parts, int $k): bool { @@ -158,18 +141,16 @@ protected function shouldStopMapping(array $parts, int $k): bool return true; } - - return strlen($lastPart->getValue()) >= 3; } /** * indicates if the given part should be ignored (skipped) during mapping * - * @param $part * @return bool */ - protected function isIgnoredPart($part) { + protected function isIgnoredPart($part) + { return $part instanceof Suffix || $part instanceof Nickname || $part instanceof Salutation; } @@ -178,9 +159,6 @@ protected function isIgnoredPart($part) { * * if the mapping did not derive any lastname this is called to transform * any previously ignored parts into lastname parts - * - * @param array $parts - * @return array */ protected function remapIgnored(array $parts): array { @@ -189,7 +167,7 @@ protected function remapIgnored(array $parts): array while (--$k >= 0) { $part = $parts[$k]; - if (!$this->isIgnoredPart($part)) { + if (! $this->isIgnoredPart($part)) { break; } @@ -199,16 +177,11 @@ protected function remapIgnored(array $parts): array return $parts; } - /** - * @param array $parts - * @param int $index - * @return bool - */ protected function isFollowedByLastnamePart(array $parts, int $index): bool { $next = $this->skipNicknameParts($parts, $index + 1); - return (isset($parts[$next]) && $parts[$next] instanceof Lastname); + return isset($parts[$next]) && $parts[$next] instanceof Lastname; } /** @@ -220,14 +193,10 @@ protected function isFollowedByLastnamePart(array $parts, int $index): bool * the name (this effectively prioritises firstname over prefix matching). * * This expects the parts array and index to be in the original order. - * - * @param array $parts - * @param int $index - * @return bool */ protected function isApplicablePrefix(array $parts, int $index): bool { - if (!$this->isPrefix($parts[$index])) { + if (! $this->isPrefix($parts[$index])) { return false; } @@ -237,19 +206,16 @@ protected function isApplicablePrefix(array $parts, int $index): bool /** * check if the given word is a lastname prefix * - * @param string $word the word to check - * @return bool + * @param string $word the word to check */ protected function isPrefix($word): bool { - return (array_key_exists($this->getKey($word), $this->prefixes)); + return array_key_exists($this->getKey($word), $this->prefixes); } /** * find the next non-nickname index in parts * - * @param $parts - * @param $startIndex * @return int|void */ protected function skipNicknameParts($parts, $startIndex) @@ -257,7 +223,7 @@ protected function skipNicknameParts($parts, $startIndex) $total = count($parts); for ($i = $startIndex; $i < $total; $i++) { - if (!($parts[$i] instanceof Nickname)) { + if (! ($parts[$i] instanceof Nickname)) { return $i; } } diff --git a/src/Mapper/MiddlenameMapper.php b/src/Mapper/MiddlenameMapper.php index 8755db3..822807a 100644 --- a/src/Mapper/MiddlenameMapper.php +++ b/src/Mapper/MiddlenameMapper.php @@ -19,7 +19,7 @@ public function __construct(bool $mapWithoutLastname = false) /** * map middlenames in the parts array * - * @param array $parts the name parts + * @param array $parts the name parts * @return array the mapped parts */ public function map(array $parts): array @@ -33,7 +33,7 @@ public function map(array $parts): array $start = $this->findFirstMapped(Firstname::class, $parts); - if (false === $start) { + if ($start === false) { return $parts; } @@ -41,9 +41,8 @@ public function map(array $parts): array } /** - * @param $start - * @param $parts - * @return mixed + * @param int $start + * @param array $parts */ protected function mapFrom($start, $parts): array { diff --git a/src/Mapper/NicknameMapper.php b/src/Mapper/NicknameMapper.php index e278f0e..49b36ab 100644 --- a/src/Mapper/NicknameMapper.php +++ b/src/Mapper/NicknameMapper.php @@ -16,12 +16,12 @@ class NicknameMapper extends AbstractMapper '(' => ')', '<' => '>', '"' => '"', - '\'' => '\'' + '\'' => '\'', ]; public function __construct(array $delimiters = []) { - if (!empty($delimiters)) { + if (! empty($delimiters)) { $this->delimiters = $delimiters; } } @@ -29,7 +29,7 @@ public function __construct(array $delimiters = []) /** * map nicknames in the parts array * - * @param array $parts the name parts + * @param array $parts the name parts * @return array the mapped parts */ public function map(array $parts): array @@ -51,7 +51,7 @@ public function map(array $parts): array $closingDelimiter = $this->delimiters[$matches[1]]; } - if (!$isEncapsulated) { + if (! $isEncapsulated) { continue; } diff --git a/src/Mapper/SalutationMapper.php b/src/Mapper/SalutationMapper.php index 0bb0ad7..fa144c0 100644 --- a/src/Mapper/SalutationMapper.php +++ b/src/Mapper/SalutationMapper.php @@ -20,7 +20,7 @@ public function __construct(array $salutations, $maxIndex = 0) /** * map salutations in the parts array * - * @param array $parts the name parts + * @param array $parts the name parts * @return array the mapped parts */ public function map(array $parts): array @@ -42,15 +42,12 @@ public function map(array $parts): array * We pass the full parts array and the current position to allow * not only single-word matches but also combined matches with * subsequent words (parts). - * - * @param array $parts - * @param int $start - * @return array */ protected function substituteWithSalutation(array $parts, int $start): array { if ($this->isSalutation($parts[$start])) { $parts[$start] = new Salutation($parts[$start], $this->salutations[$this->getKey($parts[$start])]); + return $parts; } @@ -62,6 +59,7 @@ protected function substituteWithSalutation(array $parts, int $start): array if ($this->isMatchingSubset($keys, $subset)) { array_splice($parts, $start, $length, [new Salutation(implode(' ', $subset), $salutation)]); + return $parts; } } @@ -73,10 +71,6 @@ protected function substituteWithSalutation(array $parts, int $start): array * check if the given subset matches the given keys entry by entry, * which means word by word, except that we first need to key-ify * the subset words - * - * @param array $keys - * @param array $subset - * @return bool */ private function isMatchingSubset(array $keys, array $subset): bool { @@ -92,11 +86,10 @@ private function isMatchingSubset(array $keys, array $subset): bool /** * check if the given word is a viable salutation * - * @param string $word the word to check - * @return bool + * @param string $word the word to check */ protected function isSalutation($word): bool { - return (array_key_exists($this->getKey($word), $this->salutations)); + return array_key_exists($this->getKey($word), $this->salutations); } } diff --git a/src/Mapper/SuffixMapper.php b/src/Mapper/SuffixMapper.php index 707c217..a40f627 100644 --- a/src/Mapper/SuffixMapper.php +++ b/src/Mapper/SuffixMapper.php @@ -23,13 +23,14 @@ public function __construct(array $suffixes, bool $matchSinglePart = false, int /** * map suffixes in the parts array * - * @param array $parts the name parts + * @param array $parts the name parts * @return array the mapped parts */ public function map(array $parts): array { if ($this->isMatchingSinglePart($parts)) { $parts[0] = new Suffix($parts[0], $this->suffixes[$this->getKey($parts[0])]); + return $parts; } @@ -38,7 +39,7 @@ public function map(array $parts): array for ($k = $start; $k > $this->reservedParts - 1; $k--) { $part = $parts[$k]; - if (!$this->isSuffix($part)) { + if (! $this->isSuffix($part)) { break; } @@ -48,33 +49,25 @@ public function map(array $parts): array return $parts; } - /** - * @param $parts - * @return bool - */ protected function isMatchingSinglePart($parts): bool { - if (!$this->matchSinglePart) { + if (! $this->matchSinglePart) { return false; } - if (1 !== count($parts)) { + if (count($parts) !== 1) { return false; } return $this->isSuffix($parts[0]); } - /** - * @param $part - * @return bool - */ protected function isSuffix($part): bool { if ($part instanceof AbstractPart) { return false; } - return (array_key_exists($this->getKey($part), $this->suffixes)); + return array_key_exists($this->getKey($part), $this->suffixes); } } diff --git a/src/Name.php b/src/Name.php index ab2cdf0..149679e 100644 --- a/src/Name.php +++ b/src/Name.php @@ -3,7 +3,6 @@ namespace CodeByZach\NameParser; use CodeByZach\NameParser\Part\AbstractPart; -use CodeByZach\NameParser\Part\GivenNamePart; class Name { @@ -16,19 +15,14 @@ class Name /** * constructor takes the array of parts this name consists of - * - * @param array|null $parts */ public function __construct(?array $parts = null) { - if (null !== $parts) { + if ($parts !== null) { $this->setParts($parts); } } - /** - * @return string - */ public function __toString(): string { return implode(' ', $this->getAll(true)); @@ -37,7 +31,6 @@ public function __toString(): string /** * set the parts this name consists of * - * @param array $parts * @return $this */ public function setParts(array $parts): Name @@ -49,18 +42,12 @@ public function setParts(array $parts): Name /** * get the parts this name consists of - * - * @return array */ public function getParts(): array { return $this->parts; } - /** - * @param bool $format - * @return array - */ public function getAll(bool $format = false): array { $results = []; @@ -76,9 +63,9 @@ public function getAll(bool $format = false): array foreach ($keys as $key => $args) { $method = sprintf('get%s', ucfirst($key)); - if ($value = call_user_func_array(array($this, $method), $args)) { + if ($value = call_user_func_array([$this, $method], $args)) { $results[$key] = $value; - }; + } } return $results; @@ -87,8 +74,6 @@ public function getAll(bool $format = false): array /** * get the given name (first name, middle names and initials) * in the order they were entered while still applying normalisation - * - * @return string */ public function getGivenName(): string { @@ -97,8 +82,6 @@ public function getGivenName(): string /** * get the given name followed by the last name (including any prefixes) - * - * @return string */ public function getFullName(): string { @@ -107,8 +90,6 @@ public function getFullName(): string /** * get the first name - * - * @return string */ public function getFirstname(): string { @@ -117,9 +98,6 @@ public function getFirstname(): string /** * get the last name - * - * @param bool $pure - * @return string */ public function getLastname(bool $pure = false): string { @@ -128,8 +106,6 @@ public function getLastname(bool $pure = false): string /** * get the last name prefix - * - * @return string */ public function getLastnamePrefix(): string { @@ -138,8 +114,6 @@ public function getLastnamePrefix(): string /** * get the initials - * - * @return string */ public function getInitials(): string { @@ -148,8 +122,6 @@ public function getInitials(): string /** * get the suffix(es) - * - * @return string */ public function getSuffix(): string { @@ -158,8 +130,6 @@ public function getSuffix(): string /** * get the salutation(s) - * - * @return string */ public function getSalutation(): string { @@ -168,9 +138,6 @@ public function getSalutation(): string /** * get the nick name(s) - * - * @param bool $wrap - * @return string */ public function getNickname(bool $wrap = false): string { @@ -183,8 +150,6 @@ public function getNickname(bool $wrap = false): string /** * get the middle name(s) - * - * @return string */ public function getMiddlename(): string { @@ -193,10 +158,6 @@ public function getMiddlename(): string /** * helper method used by getters to extract and format relevant name parts - * - * @param string $type - * @param bool $strict - * @return string */ protected function export(string $type, bool $strict = false): string { @@ -208,16 +169,11 @@ protected function export(string $type, bool $strict = false): string } } - return implode(' ', $matched); + return implode(' ', $matched); } /** * helper method to check if a part is of the given type - * - * @param AbstractPart $part - * @param string $type - * @param bool $strict - * @return bool */ protected function isType(AbstractPart $part, string $type, bool $strict = false): bool { diff --git a/src/Parser.php b/src/Parser.php index d58ed91..b457bc9 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -3,13 +3,13 @@ namespace CodeByZach\NameParser; use CodeByZach\NameParser\Language\English; -use CodeByZach\NameParser\Mapper\NicknameMapper; -use CodeByZach\NameParser\Mapper\SalutationMapper; -use CodeByZach\NameParser\Mapper\SuffixMapper; +use CodeByZach\NameParser\Mapper\FirstnameMapper; use CodeByZach\NameParser\Mapper\InitialMapper; use CodeByZach\NameParser\Mapper\LastnameMapper; -use CodeByZach\NameParser\Mapper\FirstnameMapper; use CodeByZach\NameParser\Mapper\MiddlenameMapper; +use CodeByZach\NameParser\Mapper\NicknameMapper; +use CodeByZach\NameParser\Mapper\SalutationMapper; +use CodeByZach\NameParser\Mapper\SuffixMapper; class Parser { @@ -60,8 +60,7 @@ public function __construct(array $languages = []) * - surname / last name * - suffix (II, Phd, Jr, etc) * - * @param string $name - * @return Name + * @param string $name */ public function parse($name): Name { @@ -69,7 +68,7 @@ public function parse($name): Name $segments = explode(',', $name); - if (1 < count($segments)) { + if (count($segments) > 1) { return $this->parseSplitName($segments[0], $segments[1], $segments[2] ?? ''); } @@ -85,10 +84,8 @@ public function parse($name): Name /** * handles split-parsing of comma-separated name parts * - * @param $left - the name part left of the comma - * @param $right - the name part right of the comma - * - * @return Name + * @param $left - the name part left of the comma + * @param $right - the name part right of the comma */ protected function parseSplitName($first, $second, $third): Name { @@ -101,9 +98,6 @@ protected function parseSplitName($first, $second, $third): Name return new Name($parts); } - /** - * @return Parser - */ protected function getFirstSegmentParser(): Parser { $parser = new Parser(); @@ -119,9 +113,6 @@ protected function getFirstSegmentParser(): Parser return $parser; } - /** - * @return Parser - */ protected function getSecondSegmentParser(): Parser { $parser = new Parser(); @@ -151,8 +142,6 @@ protected function getThirdSegmentParser(): Parser /** * get the mappers for this parser - * - * @return array */ public function getMappers(): array { @@ -173,9 +162,6 @@ public function getMappers(): array /** * set the mappers for this parser - * - * @param array $mappers - * @return Parser */ public function setMappers(array $mappers): Parser { @@ -186,9 +172,6 @@ public function setMappers(array $mappers): Parser /** * normalize the name - * - * @param string $name - * @return string */ protected function normalize(string $name): string { @@ -196,13 +179,11 @@ protected function normalize(string $name): string $name = trim($name); - return preg_replace('/[' . preg_quote($whitespace) . ']+/', ' ', $name); + return preg_replace('/[' . preg_quote($whitespace, '/') . ']+/', ' ', $name); } /** * get a string of characters that are supposed to be treated as whitespace - * - * @return string */ public function getWhitespace(): string { @@ -211,9 +192,6 @@ public function getWhitespace(): string /** * set the string of characters that are supposed to be treated as whitespace - * - * @param $whitespace - * @return Parser */ public function setWhitespace($whitespace): Parser { @@ -267,18 +245,11 @@ protected function getSalutations() return $salutations; } - /** - * @return array - */ public function getNicknameDelimiters(): array { return $this->nicknameDelimiters; } - /** - * @param array $nicknameDelimiters - * @return Parser - */ public function setNicknameDelimiters(array $nicknameDelimiters): Parser { $this->nicknameDelimiters = $nicknameDelimiters; @@ -286,18 +257,11 @@ public function setNicknameDelimiters(array $nicknameDelimiters): Parser return $this; } - /** - * @return int - */ public function getMaxSalutationIndex(): int { return $this->maxSalutationIndex; } - /** - * @param int $maxSalutationIndex - * @return Parser - */ public function setMaxSalutationIndex(int $maxSalutationIndex): Parser { $this->maxSalutationIndex = $maxSalutationIndex; @@ -305,18 +269,11 @@ public function setMaxSalutationIndex(int $maxSalutationIndex): Parser return $this; } - /** - * @return int - */ public function getMaxCombinedInitials(): int { return $this->maxCombinedInitials; } - /** - * @param int $maxCombinedInitials - * @return Parser - */ public function setMaxCombinedInitials(int $maxCombinedInitials): Parser { $this->maxCombinedInitials = $maxCombinedInitials; diff --git a/src/Part/AbstractPart.php b/src/Part/AbstractPart.php index cea9c7d..21e9b2f 100644 --- a/src/Part/AbstractPart.php +++ b/src/Part/AbstractPart.php @@ -11,8 +11,6 @@ abstract class AbstractPart /** * constructor allows passing the value to wrap - * - * @param $value */ public function __construct($value) { @@ -23,7 +21,7 @@ public function __construct($value) * set the value to wrap * (can take string or part instance) * - * @param string|AbstractPart $value + * @param string|AbstractPart $value * @return $this */ public function setValue($value): AbstractPart @@ -39,8 +37,6 @@ public function setValue($value): AbstractPart /** * get the wrapped value - * - * @return string */ public function getValue(): string { @@ -49,8 +45,6 @@ public function getValue(): string /** * get the normalized value - * - * @return string */ public function normalize(): string { @@ -61,8 +55,7 @@ public function normalize(): string * helper for camelization of values * to be used during normalize * - * @param $word - * @return mixed + * @param string $word */ protected function camelcase($word): string { @@ -75,16 +68,13 @@ protected function camelcase($word): string /** * camelcasing callback - * - * @param $matches - * @return string */ protected function camelcaseReplace($matches): string { if (function_exists('mb_convert_case')) { return mb_convert_case($matches[0], MB_CASE_TITLE, 'UTF-8'); } - + return ucfirst(strtolower($matches[0])); } } diff --git a/src/Part/Firstname.php b/src/Part/Firstname.php index e762946..d5a24f4 100644 --- a/src/Part/Firstname.php +++ b/src/Part/Firstname.php @@ -2,6 +2,4 @@ namespace CodeByZach\NameParser\Part; -class Firstname extends GivenNamePart -{ -} +class Firstname extends GivenNamePart {} diff --git a/src/Part/GivenNamePart.php b/src/Part/GivenNamePart.php index 7d1f77b..9ed1336 100644 --- a/src/Part/GivenNamePart.php +++ b/src/Part/GivenNamePart.php @@ -2,6 +2,4 @@ namespace CodeByZach\NameParser\Part; -abstract class GivenNamePart extends NamePart -{ -} +abstract class GivenNamePart extends NamePart {} diff --git a/src/Part/Initial.php b/src/Part/Initial.php index bb1cf20..8f2b081 100644 --- a/src/Part/Initial.php +++ b/src/Part/Initial.php @@ -6,8 +6,6 @@ class Initial extends GivenNamePart { /** * uppercase the initial - * - * @return string */ public function normalize(): string { diff --git a/src/Part/Lastname.php b/src/Part/Lastname.php index d597dcf..e24946e 100644 --- a/src/Part/Lastname.php +++ b/src/Part/Lastname.php @@ -2,6 +2,4 @@ namespace CodeByZach\NameParser\Part; -class Lastname extends NamePart -{ -} +class Lastname extends NamePart {} diff --git a/src/Part/LastnamePrefix.php b/src/Part/LastnamePrefix.php index 6e67bbd..e099677 100644 --- a/src/Part/LastnamePrefix.php +++ b/src/Part/LastnamePrefix.php @@ -16,8 +16,6 @@ public function __construct(string $value, ?string $normalized = null) /** * if this is a lastname prefix, look up normalized version from registry * otherwise camelcase the lastname - * - * @return string */ public function normalize(): string { diff --git a/src/Part/Middlename.php b/src/Part/Middlename.php index 605685f..de7060d 100644 --- a/src/Part/Middlename.php +++ b/src/Part/Middlename.php @@ -2,6 +2,4 @@ namespace CodeByZach\NameParser\Part; -class Middlename extends GivenNamePart -{ -} +class Middlename extends GivenNamePart {} diff --git a/src/Part/NamePart.php b/src/Part/NamePart.php index 4085c18..349727f 100644 --- a/src/Part/NamePart.php +++ b/src/Part/NamePart.php @@ -6,8 +6,6 @@ abstract class NamePart extends AbstractPart { /** * camelcase the lastname - * - * @return string */ public function normalize(): string { diff --git a/src/Part/Nickname.php b/src/Part/Nickname.php index c22187b..9faa168 100644 --- a/src/Part/Nickname.php +++ b/src/Part/Nickname.php @@ -6,8 +6,6 @@ class Nickname extends AbstractPart { /** * camelcase the nickname for normalization - * - * @return string */ public function normalize(): string { diff --git a/src/Part/PreNormalizedPart.php b/src/Part/PreNormalizedPart.php index 0386df9..c7a6ed5 100644 --- a/src/Part/PreNormalizedPart.php +++ b/src/Part/PreNormalizedPart.php @@ -16,8 +16,6 @@ public function __construct(string $value, ?string $normalized = null) /** * if this is a lastname prefix, look up normalized version from registry * otherwise camelcase the lastname - * - * @return string */ public function normalize(): string { diff --git a/src/Part/Salutation.php b/src/Part/Salutation.php index d323850..04ae606 100644 --- a/src/Part/Salutation.php +++ b/src/Part/Salutation.php @@ -2,7 +2,4 @@ namespace CodeByZach\NameParser\Part; -class Salutation extends PreNormalizedPart -{ - -} +class Salutation extends PreNormalizedPart {} diff --git a/src/Part/Suffix.php b/src/Part/Suffix.php index c27fe0b..453bcb5 100644 --- a/src/Part/Suffix.php +++ b/src/Part/Suffix.php @@ -2,7 +2,4 @@ namespace CodeByZach\NameParser\Part; -class Suffix extends PreNormalizedPart -{ - -} +class Suffix extends PreNormalizedPart {} diff --git a/tests/GermanParserTest.php b/tests/GermanParserTest.php index 897049d..57ceca2 100644 --- a/tests/GermanParserTest.php +++ b/tests/GermanParserTest.php @@ -21,7 +21,7 @@ public static function provider() [ 'salutation' => 'Herr', 'lastname' => 'Schmidt', - ] + ], ], [ 'Frau Maria Lange', @@ -29,7 +29,7 @@ public static function provider() 'salutation' => 'Frau', 'firstname' => 'Maria', 'lastname' => 'Lange', - ] + ], ], [ 'Hr. Juergen von der Lippe', @@ -37,7 +37,7 @@ public static function provider() 'salutation' => 'Herr', 'firstname' => 'Juergen', 'lastname' => 'von der Lippe', - ] + ], ], [ 'Fr. Charlotte von Stein', @@ -45,7 +45,7 @@ public static function provider() 'salutation' => 'Frau', 'firstname' => 'Charlotte', 'lastname' => 'von Stein', - ] + ], ], ]; } @@ -54,7 +54,7 @@ public static function provider() public function testParse($input, $expectation) { $parser = new Parser([ - new German() + new German(), ]); $name = $parser->parse($input); diff --git a/tests/Mapper/FirstnameMapperTest.php b/tests/Mapper/FirstnameMapperTest.php index 014d9fd..f8d8c6b 100644 --- a/tests/Mapper/FirstnameMapperTest.php +++ b/tests/Mapper/FirstnameMapperTest.php @@ -57,8 +57,8 @@ public static function provider() 'expectation' => [ new Firstname('Alfonso'), new Salutation('Mr'), - ] - ] + ], + ], ]; } diff --git a/tests/Mapper/InitialMapperTest.php b/tests/Mapper/InitialMapperTest.php index 6f1c79c..9fb5ea7 100644 --- a/tests/Mapper/InitialMapperTest.php +++ b/tests/Mapper/InitialMapperTest.php @@ -2,7 +2,6 @@ namespace Tests\CodeByZach\NameParser\Mapper; -use CodeByZach\NameParser\Language\English; use CodeByZach\NameParser\Mapper\InitialMapper; use CodeByZach\NameParser\Part\Initial; use CodeByZach\NameParser\Part\Lastname; @@ -55,17 +54,17 @@ public static function provider() [ 'input' => [ 'James', - 'B' + 'B', ], 'expectation' => [ 'James', - 'B' + 'B', ], ], [ 'input' => [ 'James', - 'B' + 'B', ], 'expectation' => [ 'James', @@ -73,7 +72,7 @@ public static function provider() ], 'arguments' => [ 2, - true + true, ], ], [ @@ -84,8 +83,8 @@ public static function provider() 'expectation' => [ new Initial('J'), new Initial('M'), - 'Walker' - ] + 'Walker', + ], ], [ 'input' => [ @@ -94,12 +93,12 @@ public static function provider() ], 'expectation' => [ 'JM', - 'Walker' + 'Walker', ], 'arguments' => [ - 1 - ] - ] + 1, + ], + ], ]; } diff --git a/tests/Mapper/LastnameMapperTest.php b/tests/Mapper/LastnameMapperTest.php index 6d57051..3fc5903 100644 --- a/tests/Mapper/LastnameMapperTest.php +++ b/tests/Mapper/LastnameMapperTest.php @@ -99,10 +99,10 @@ public static function provider() ], [ 'input' => [ - 'Kirk' + 'Kirk', ], 'expectation' => [ - 'Kirk' + 'Kirk', ], ], [ @@ -113,9 +113,9 @@ public static function provider() new Lastname('Kirk'), ], 'arguments' => [ - true + true, ], - ] + ], ]; } diff --git a/tests/Mapper/MiddlenameMapperTest.php b/tests/Mapper/MiddlenameMapperTest.php index d67d664..badd1d0 100644 --- a/tests/Mapper/MiddlenameMapperTest.php +++ b/tests/Mapper/MiddlenameMapperTest.php @@ -6,7 +6,6 @@ use CodeByZach\NameParser\Part\Firstname; use CodeByZach\NameParser\Part\Lastname; use CodeByZach\NameParser\Part\Middlename; -use CodeByZach\NameParser\Part\Salutation; class MiddlenameMapperTest extends AbstractMapperTestCase { @@ -88,7 +87,7 @@ public static function provider() new Middlename('Tiberius'), ], 'arguments' => [ - true + true, ], ], ]; diff --git a/tests/Mapper/NicknameMapperTest.php b/tests/Mapper/NicknameMapperTest.php index 5ee9f96..eca5d2e 100644 --- a/tests/Mapper/NicknameMapperTest.php +++ b/tests/Mapper/NicknameMapperTest.php @@ -118,7 +118,7 @@ protected function getMapper() '(' => ')', '<' => '>', '"' => '"', - '\'' => '\'' + '\'' => '\'', ]); } } diff --git a/tests/Mapper/SalutationMapperTest.php b/tests/Mapper/SalutationMapperTest.php index b169803..cc782f9 100644 --- a/tests/Mapper/SalutationMapperTest.php +++ b/tests/Mapper/SalutationMapperTest.php @@ -5,7 +5,6 @@ use CodeByZach\NameParser\Language\English; use CodeByZach\NameParser\Mapper\SalutationMapper; use CodeByZach\NameParser\Part\Firstname; -use CodeByZach\NameParser\Part\Lastname; use CodeByZach\NameParser\Part\Salutation; class SalutationMapperTest extends AbstractMapperTestCase diff --git a/tests/ParserTest.php b/tests/ParserTest.php index ee9c74b..d4c8bf1 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -2,7 +2,6 @@ namespace Tests\CodeByZach\NameParser; -use CodeByZach\NameParser\Language\English; use CodeByZach\NameParser\Language\German; use CodeByZach\NameParser\Name; use CodeByZach\NameParser\Parser; @@ -22,7 +21,7 @@ public static function provider() [ 'firstname' => 'James', 'lastname' => 'Norrington', - ] + ], ], [ @@ -31,7 +30,7 @@ public static function provider() 'firstname' => 'Hans', 'lastname' => 'Anderssen', 'middlename' => 'Christian', - ] + ], ], [ 'Mr Anthony R Von Fange III', @@ -41,7 +40,7 @@ public static function provider() 'initials' => 'R', 'lastname' => 'von Fange', 'suffix' => 'III', - ] + ], ], [ 'J. B. Hunt', @@ -49,7 +48,7 @@ public static function provider() 'firstname' => 'J.', 'initials' => 'B.', 'lastname' => 'Hunt', - ] + ], ], [ 'J.B. Hunt', @@ -57,23 +56,23 @@ public static function provider() 'firstname' => 'J', 'initials' => 'B', 'lastname' => 'Hunt', - ] + ], ], [ 'Edward Senior III', [ 'firstname' => 'Edward', 'lastname' => 'Senior', - 'suffix' => 'III' - ] + 'suffix' => 'III', + ], ], [ 'Edward Dale Senior II', [ 'firstname' => 'Edward', 'lastname' => 'Dale', - 'suffix' => 'Senior II' - ] + 'suffix' => 'Senior II', + ], ], [ 'Dale Edward Jones Senior', @@ -81,30 +80,30 @@ public static function provider() 'firstname' => 'Dale', 'middlename' => 'Edward', 'lastname' => 'Jones', - 'suffix' => 'Senior' - ] + 'suffix' => 'Senior', + ], ], [ 'Jason Rodriguez Sr.', [ 'firstname' => 'Jason', 'lastname' => 'Rodriguez', - 'suffix' => 'Sr' - ] + 'suffix' => 'Sr', + ], ], [ 'Jason Senior', [ 'firstname' => 'Jason', 'lastname' => 'Senior', - ] + ], ], [ 'Bill Junior', [ 'firstname' => 'Bill', 'lastname' => 'Junior', - ] + ], ], [ 'Sara Ann Fraser', @@ -112,34 +111,34 @@ public static function provider() 'firstname' => 'Sara', 'middlename' => 'Ann', 'lastname' => 'Fraser', - ] + ], ], [ 'Adam', [ 'firstname' => 'Adam', - ] + ], ], [ 'OLD MACDONALD', [ 'firstname' => 'Old', 'lastname' => 'Macdonald', - ] + ], ], [ 'Old MacDonald', [ 'firstname' => 'Old', 'lastname' => 'MacDonald', - ] + ], ], [ 'Old McDonald', [ 'firstname' => 'Old', 'lastname' => 'McDonald', - ] + ], ], [ 'Old Mc Donald', @@ -147,7 +146,7 @@ public static function provider() 'firstname' => 'Old', 'middlename' => 'Mc', 'lastname' => 'Donald', - ] + ], ], [ 'Old Mac Donald', @@ -155,14 +154,14 @@ public static function provider() 'firstname' => 'Old', 'middlename' => 'Mac', 'lastname' => 'Donald', - ] + ], ], [ 'James van Allen', [ 'firstname' => 'James', 'lastname' => 'van Allen', - ] + ], ], [ 'Jimmy (Bubba) Smith', @@ -170,7 +169,7 @@ public static function provider() 'firstname' => 'Jimmy', 'lastname' => 'Smith', 'nickname' => 'Bubba', - ] + ], ], [ 'Miss Jennifer Shrader Lawrence', @@ -179,7 +178,7 @@ public static function provider() 'firstname' => 'Jennifer', 'middlename' => 'Shrader', 'lastname' => 'Lawrence', - ] + ], ], [ 'Dr. Jonathan Smith', @@ -187,7 +186,7 @@ public static function provider() 'salutation' => 'Dr.', 'firstname' => 'Jonathan', 'lastname' => 'Smith', - ] + ], ], [ 'Ms. Jamie P. Harrowitz', @@ -196,7 +195,7 @@ public static function provider() 'firstname' => 'Jamie', 'initials' => 'P.', 'lastname' => 'Harrowitz', - ] + ], ], [ 'Mr John Doe', @@ -204,7 +203,7 @@ public static function provider() 'salutation' => 'Mr.', 'firstname' => 'John', 'lastname' => 'Doe', - ] + ], ], [ 'Rev. Dr John Doe', @@ -212,7 +211,7 @@ public static function provider() 'salutation' => 'Rev. Dr.', 'firstname' => 'John', 'lastname' => 'Doe', - ] + ], ], [ 'Prof. Tyson J. Hirthe', @@ -221,7 +220,7 @@ public static function provider() 'lastname' => 'Hirthe', 'firstname' => 'Tyson', 'initials' => 'J.', - ] + ], ], [ 'prof Eveline Aufderhar', @@ -229,23 +228,23 @@ public static function provider() 'salutation' => 'Prof.', 'lastname' => 'Aufderhar', 'firstname' => 'Eveline', - ] + ], ], [ 'Anthony Von Fange III', [ 'firstname' => 'Anthony', 'lastname' => 'von Fange', - 'suffix' => 'III' - ] + 'suffix' => 'III', + ], ], [ 'Smarty Pants Phd', [ 'firstname' => 'Smarty', 'lastname' => 'Pants', - 'suffix' => 'PhD' - ] + 'suffix' => 'PhD', + ], ], [ 'Mark Peter Williams', @@ -253,7 +252,7 @@ public static function provider() 'firstname' => 'Mark', 'middlename' => 'Peter', 'lastname' => 'Williams', - ] + ], ], [ 'Mark P Williams', @@ -261,7 +260,7 @@ public static function provider() 'firstname' => 'Mark', 'lastname' => 'Williams', 'initials' => 'P', - ] + ], ], [ 'Mark P. Williams', @@ -269,7 +268,7 @@ public static function provider() 'firstname' => 'Mark', 'initials' => 'P.', 'lastname' => 'Williams', - ] + ], ], [ 'M Peter Williams', @@ -277,7 +276,7 @@ public static function provider() 'firstname' => 'Peter', 'initials' => 'M', 'lastname' => 'Williams', - ] + ], ], [ 'M. Peter Williams', @@ -285,7 +284,7 @@ public static function provider() 'firstname' => 'Peter', 'initials' => 'M.', 'lastname' => 'Williams', - ] + ], ], [ 'M. P. Williams', @@ -293,7 +292,7 @@ public static function provider() 'firstname' => 'M.', 'initials' => 'P.', 'lastname' => 'Williams', - ] + ], ], [ 'The Rev. Mark Williams', @@ -301,7 +300,7 @@ public static function provider() 'salutation' => 'Rev.', 'firstname' => 'Mark', 'lastname' => 'Williams', - ] + ], ], [ 'Mister Mark Williams', @@ -309,14 +308,14 @@ public static function provider() 'salutation' => 'Mr.', 'firstname' => 'Mark', 'lastname' => 'Williams', - ] + ], ], [ 'Fraser, Joshua', [ 'firstname' => 'Joshua', 'lastname' => 'Fraser', - ] + ], ], [ 'Mrs. Brown, Amanda', @@ -324,7 +323,7 @@ public static function provider() 'salutation' => 'Mrs.', 'firstname' => 'Amanda', 'lastname' => 'Brown', - ] + ], ], [ "Mr.\r\nPaul\rJoseph\nMaria\tWinters", @@ -333,7 +332,7 @@ public static function provider() 'firstname' => 'Paul', 'middlename' => 'Joseph Maria', 'lastname' => 'Winters', - ] + ], ], [ 'Van Truong', @@ -362,8 +361,8 @@ public static function provider() [ 'firstname' => 'Anthony', 'lastname' => 'von Fange', - 'suffix' => 'III PhD' - ] + 'suffix' => 'III PhD', + ], ], [ 'Jimmy (Bubba Junior) Smith', @@ -371,15 +370,15 @@ public static function provider() 'nickname' => 'Bubba Junior', 'firstname' => 'Jimmy', 'lastname' => 'Smith', - ] + ], ], [ 'Jonathan Smith, MD', [ 'firstname' => 'Jonathan', 'lastname' => 'Smith', - 'suffix' => 'MD' - ] + 'suffix' => 'MD', + ], ], [ 'Kirk, James T.', @@ -394,7 +393,7 @@ public static function provider() [ 'firstname' => 'James', 'lastname' => 'B', - ] + ], ], [ 'Williams, Hank, Jr.', @@ -402,7 +401,7 @@ public static function provider() 'firstname' => 'Hank', 'lastname' => 'Williams', 'suffix' => 'Jr', - ] + ], ], [ 'Sir James Reynolds, Junior', @@ -410,8 +409,8 @@ public static function provider() 'salutation' => 'Sir', 'firstname' => 'James', 'lastname' => 'Reynolds', - 'suffix' => 'Junior' - ] + 'suffix' => 'Junior', + ], ], [ 'Sir John Paul Getty Sr.', @@ -421,29 +420,29 @@ public static function provider() 'middlename' => 'Paul', 'lastname' => 'Getty', 'suffix' => 'Sr', - ] + ], ], [ 'etna übel', [ 'firstname' => 'Etna', 'lastname' => 'Übel', - ] + ], ], [ 'Markus Müller', [ 'firstname' => 'Markus', 'lastname' => 'Müller', - ] + ], ], [ 'Charles Dixon (20th century)', [ 'firstname' => 'Charles', 'lastname' => 'Dixon', - 'nickname' => '20Th Century' - ] + 'nickname' => '20Th Century', + ], ], [ 'Smith, John Eric', @@ -451,7 +450,7 @@ public static function provider() 'lastname' => 'Smith', 'firstname' => 'John', 'middlename' => 'Eric', - ] + ], ], [ 'PAUL M LEWIS MR', @@ -459,7 +458,7 @@ public static function provider() 'firstname' => 'Paul', 'initials' => 'M', 'lastname' => 'Lewis Mr', - ] + ], ], [ 'SUJAN MASTER', @@ -474,7 +473,7 @@ public static function provider() 'firstname' => 'James', 'initials' => 'J', 'lastname' => 'Ma', - ] + ], ], [ 'Tiptree, James, Jr.', @@ -482,7 +481,7 @@ public static function provider() 'lastname' => 'Tiptree', 'firstname' => 'James', 'suffix' => 'Jr', - ] + ], ], [ 'Miller, Walter M., Jr.', @@ -491,7 +490,7 @@ public static function provider() 'firstname' => 'Walter', 'initials' => 'M.', 'suffix' => 'Jr', - ] + ], ], [ 'Tiptree, James Jr.', @@ -499,7 +498,7 @@ public static function provider() 'lastname' => 'Tiptree', 'firstname' => 'James', 'suffix' => 'Jr', - ] + ], ], [ 'Miller, Walter M. Jr.', @@ -508,7 +507,7 @@ public static function provider() 'firstname' => 'Walter', 'initials' => 'M.', 'suffix' => 'Jr', - ] + ], ], [ 'Thái Quốc Nguyễn', @@ -516,28 +515,28 @@ public static function provider() 'lastname' => 'Nguyễn', 'middlename' => 'Quốc', 'firstname' => 'Thái', - ] + ], ], [ 'Yumeng Du', [ 'lastname' => 'Du', 'firstname' => 'Yumeng', - ] + ], ], [ 'Her Honour Mrs Judy', [ 'lastname' => 'Judy', - 'salutation' => 'Her Honour Mrs.' - ] + 'salutation' => 'Her Honour Mrs.', + ], ], [ 'Etje Heijdanus-De Boer', [ 'firstname' => 'Etje', 'lastname' => 'Heijdanus-De Boer', - ] + ], ], [ 'JB Hunt', @@ -545,7 +544,7 @@ public static function provider() 'firstname' => 'J', 'initials' => 'B', 'lastname' => 'Hunt', - ] + ], ], [ 'Charles Philip Arthur George Mountbatten-Windsor', @@ -553,7 +552,7 @@ public static function provider() 'firstname' => 'Charles', 'middlename' => 'Philip Arthur George', 'lastname' => 'Mountbatten-Windsor', - ] + ], ], [ 'Ella Marija Lani Yelich-O\'Connor', @@ -561,8 +560,8 @@ public static function provider() 'firstname' => 'Ella', 'middlename' => 'Marija Lani', 'lastname' => 'Yelich-O\'Connor', - ] - ] + ], + ], ]; } diff --git a/tests/Part/AbstractPartTest.php b/tests/Part/AbstractPartTest.php index bd6bd6e..d3c5b7a 100644 --- a/tests/Part/AbstractPartTest.php +++ b/tests/Part/AbstractPartTest.php @@ -9,16 +9,16 @@ class AbstractPartTest extends TestCase { public function testNormalize() { - $part = new class('abc') extends AbstractPart {}; + $part = new class ('abc') extends AbstractPart {}; $this->assertEquals('abc', $part->normalize()); } public function testSetValueUnwraps() { - $part = new class('abc') extends AbstractPart {}; + $part = new class ('abc') extends AbstractPart {}; $this->assertEquals('abc', $part->getValue()); - $wrapped = new class($part) extends AbstractPart {}; + $wrapped = new class ($part) extends AbstractPart {}; $this->assertEquals('abc', $wrapped->getValue()); } } diff --git a/tests/Part/NormalisationTest.php b/tests/Part/NormalisationTest.php index d9c3263..311da18 100644 --- a/tests/Part/NormalisationTest.php +++ b/tests/Part/NormalisationTest.php @@ -43,7 +43,7 @@ public function testCamelcasingWorksWithMbString() $part = new Lastname('nguyễn'); $this->assertEquals('Nguyễn', $part->normalize()); - } + } /** * make sure we test both with and without mb_string support diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 3a9f8b8..ebf2d4f 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,3 +1,3 @@ Date: Sun, 10 May 2026 17:08:04 -0400 Subject: [PATCH 08/14] Phase 3c: GitHub Actions CI + .gitattributes Add .github/workflows/ci.yml: - Three parallel jobs: tests (matrix PHP 8.3/8.4/8.5), static-analysis, code-style - All third-party actions SHA-pinned with version comments: * actions/checkout@93cb6efe (v5.0.1) * shivammathur/setup-php@fcafdd6392 (v2.37.0) * ramsey/composer-install@a8d0d959dab (v3.2.1) - composer audit step in tests matrix to catch known security advisories on every supported PHP version - Static-analysis and code-style jobs read PHP version from .tool-versions via setup-php's php-version-file input, so there's one source of truth for the canonical dev version - Concurrency control: cancel-in-progress for PRs (so new commits cancel stale runs), keep main branch runs sequential Add .gitattributes: - export-ignore for tests/, .github/, all dev configs (.tool-versions, phpstan*, phpunit.xml.dist, .php-cs-fixer.dist.php) - Reduces what's downloaded into consumers' vendor/ directories when they composer require this library --- .gitattributes | 12 ++++++++ .github/workflows/ci.yml | 59 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/workflows/ci.yml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..bcbf738 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,12 @@ +# Files and directories not needed by consumers of the package. +# `composer require` ships only the files NOT marked export-ignore. + +/.github export-ignore +/tests export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.php-cs-fixer.dist.php export-ignore +/.tool-versions export-ignore +/phpstan-baseline.neon export-ignore +/phpstan.neon.dist export-ignore +/phpunit.xml.dist export-ignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..81d028e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,59 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + tests: + name: Tests (PHP ${{ matrix.php }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ['8.3', '8.4', '8.5'] + steps: + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + - uses: shivammathur/setup-php@fcafdd6392932010c2bd5094439b8e33be2a8a09 # v2.37.0 + with: + php-version: ${{ matrix.php }} + extensions: mbstring + coverage: none + tools: composer:v2 + - uses: ramsey/composer-install@a8d0d959dab41457692a5e2041bd9b757a119e3f # v3.2.1 + - run: composer audit + - run: vendor/bin/phpunit + + static-analysis: + name: Static Analysis + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + - uses: shivammathur/setup-php@fcafdd6392932010c2bd5094439b8e33be2a8a09 # v2.37.0 + with: + php-version-file: .tool-versions + coverage: none + tools: composer:v2 + - uses: ramsey/composer-install@a8d0d959dab41457692a5e2041bd9b757a119e3f # v3.2.1 + - run: vendor/bin/phpstan analyse --no-progress + + code-style: + name: Code Style + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + - uses: shivammathur/setup-php@fcafdd6392932010c2bd5094439b8e33be2a8a09 # v2.37.0 + with: + php-version-file: .tool-versions + coverage: none + tools: composer:v2 + - uses: ramsey/composer-install@a8d0d959dab41457692a5e2041bd9b757a119e3f # v3.2.1 + - run: vendor/bin/php-cs-fixer fix --dry-run --diff From 952a37e4908aead28d73614db2b7535ab506272c Mon Sep 17 00:00:00 2001 From: Zachary Miller Date: Sun, 10 May 2026 17:09:49 -0400 Subject: [PATCH 09/14] Phase 4: Update README and LICENSE for fork README: - Retitle 'THE ICONIC Name Parser' -> 'CodeByZach Name Parser' - Comment out the six theiconic/* badges (HTML-commented so they're easy to re-enable if we ever publish to Packagist under our own name) - Add a 'Fork notice' callout at the top: explains origin, what's new, and the framework-neutral runtime positioning - Update Setup section: composer require codebyzach/name-parser plus PHP version note (8.3+, tested on 8.3/8.4/8.5) - Add 'Laravel integration' subsection: shows how to bind Parser::class in AppServiceProvider; emphasizes that no Laravel-specific glue ships with the library - Add 'Local development' section: mise/.tool-versions and the four composer scripts (test, analyse, lint, lint:fix) - Add 'Contributors' section listing The Iconic (original) and CodeByZach (fork maintainer) - Update License section: prose -> link to LICENSE file with dual copyright attribution - Update upstream test link to point to the fork's ParserTest.php - Replace dead $xslt code-fence syntax with bash LICENSE: - Add 'Copyright (c) 2026 Zachary Miller (CodeByZach)' line below the preserved 'Copyright (c) 2017 THE ICONIC' line. MIT body covers both copyright holders unchanged. --- LICENSE | 1 + README.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/LICENSE b/LICENSE index fdcc19e..f2599bf 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ The MIT License (MIT) Copyright (c) 2017 THE ICONIC +Copyright (c) 2026 Zachary Miller (CodeByZach) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 3b7a1ae..5c1dc48 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,20 @@ -# THE ICONIC Name Parser +# CodeByZach Name Parser + + +> **Fork notice**: This is a maintained fork of [theiconic/name-parser](https://github.com/theiconic/name-parser), +> which has been effectively dormant since ~2020. This fork targets PHP 8.3+ +> (tested through 8.5), ships expanded English dictionary entries, and uses +> modernized tooling (PHPUnit 12, PHPStan 2, PHP-CS-Fixer, GitHub Actions). +> The library is framework-neutral at runtime and integrates cleanly into +> Laravel, Symfony, or vanilla PHP projects — no framework dependencies. ## Purpose This is a universal, language-independent name parser. @@ -24,7 +33,7 @@ E.g. **Mr Anthony R Von Fange III** is parsed to - lastname: **von Fange** - suffix: **III** -This package has been used by The Iconic in production for years, +The original library was used by The Iconic in production for years, successfully processing hundreds of thousands of customer names. ## Features @@ -60,13 +69,16 @@ This parser is able to handle name patterns with and without comma: ## Examples More than 60 different successfully parsed name patterns can be found in the -[parser unit test](https://github.com/theiconic/name-parser/blob/master/tests/ParserTest.php#L12-L12). +[parser unit test](https://github.com/CodeByZach/name-parser/blob/master/tests/ParserTest.php). ## Setup -```$xslt + +```bash composer require codebyzach/name-parser ``` +Requires PHP 8.3 or newer (tested on 8.3, 8.4, and 8.5). + ## Usage ### Basic usage @@ -91,6 +103,34 @@ echo $name; ``` An empty string is returned for missing parts. +### Laravel integration + +The library is framework-neutral and ships no Laravel-specific glue (no +service provider, no facade). Bind it in your own `AppServiceProvider` if +you want it resolvable from the container: + +```php +// app/Providers/AppServiceProvider.php +use CodeByZach\NameParser\Parser; + +public function register(): void +{ + $this->app->singleton(Parser::class); +} +``` + +Then inject or resolve as usual: + +```php +use CodeByZach\NameParser\Parser; + +public function store(Request $request, Parser $parser) +{ + $name = $parser->parse($request->input('full_name')); + // ... +} +``` + ### Special part retrieval features #### Explicit last name parts You can retrieve last name prefixes and pure last names separately with @@ -248,6 +288,26 @@ gist. Of course this can also be used in more useful ways, e.g. to spell out abbreviated titles, like `Prof.` as `Professor` etc. . +## Local development + +This repo uses [mise](https://mise.jdx.dev/) (or [asdf](https://asdf-vm.com/)) +for PHP version pinning via `.tool-versions`. After cloning: + +```bash +mise install # installs the pinned PHP version +composer install # installs dev dependencies +composer test # run the test suite +composer analyse # run PHPStan +composer lint # check code style (dry-run) +composer lint:fix # apply code style fixes +``` + +## Contributors + +- **The Iconic** ([@theiconic](https://github.com/theiconic)) — original library author +- **Zachary Miller** ([@CodeByZach](https://github.com/CodeByZach)) — fork maintainer + ## License -THE ICONIC Name Parser library for PHP is released under the MIT License. +Released under the [MIT License](LICENSE). Original work © 2017 The Iconic; +fork modifications © 2026 Zachary Miller (CodeByZach). From 5fd284a9f3cb54e65de1f1169f65b932dce88add Mon Sep 17 00:00:00 2001 From: Zachary Miller Date: Sun, 10 May 2026 17:27:38 -0400 Subject: [PATCH 10/14] Phase 3d: Modernize PHP 8 idioms (typed properties, override attributes) Type system improvements: - Add typed properties throughout: Name::\$parts (array), all 6 Parser properties, Mapper internal state, AbstractPart::\$value (string), PreNormalizedPart::\$normalized (string), LastnamePrefix::\$normalized (string), NicknameMapper::\$delimiters (array) - Constructor property promotion (PHP 8.0): SalutationMapper, MiddlenameMapper, SuffixMapper, InitialMapper, LastnameMapper now declare their state inline in the constructor signature instead of separate property + assignment boilerplate - Tighten AbstractPart constructor/setValue to accept string|AbstractPart union (previously untyped); setValue returns static for fluent chaining - AbstractMapper: add missing array return type on abstract map(); type hasUnmappedPartsBefore \$index as int; type findFirstMapped return as int|false (was untyped); type getKey \$word as string PHP 8.3 #[\Override] attributes: - Add to all overriding non-constructor methods so PHP fails at compile time if a parent method is renamed/removed: NamePart::normalize, Nickname::normalize, Initial::normalize, LastnamePrefix::normalize, PreNormalizedPart::normalize, and the map() implementation in all 7 concrete Mapper classes - Constructors deliberately not annotated (idiomatic PHP convention) Other modernization: - AbstractPart::camelcase: use first-class callable syntax \$this->camelcaseReplace(...) instead of [\$this, 'camelcaseReplace'] (PHP 8.1 syntax) - AbstractPart::camelcaseReplace: type \$matches as array Comment formatting consistency: - Restored descriptive PHPDoc on AbstractPart constructor/setValue/getValue and PreNormalizedPart/LastnamePrefix normalize() that I'd over-aggressively trimmed in earlier passes (they explained intent, not types) - Standardize all property/method PHPDoc to multi-line block style to match the existing codebase convention - Add 'phpdoc_line_span' rule to .php-cs-fixer.dist.php to enforce multi-line PHPDoc going forward (property/method/const all 'multi') - Note: not introducing declare(strict_types=1) - reviewed actual usage in major libraries (Laravel framework: no, Symfony: no, Doctrine: yes); community is split, and Laravel-friendliness favors not having it Test suite still: 131 tests, 235 assertions, 0 errors/warnings/deprecations. PHPStan level 5: 0 errors. --- .php-cs-fixer.dist.php | 5 +++++ src/Mapper/AbstractMapper.php | 17 ++++------------- src/Mapper/FirstnameMapper.php | 1 + src/Mapper/InitialMapper.php | 14 +++++--------- src/Mapper/LastnameMapper.php | 17 ++++++++--------- src/Mapper/MiddlenameMapper.php | 10 ++++------ src/Mapper/NicknameMapper.php | 8 ++++++-- src/Mapper/SalutationMapper.php | 17 ++++++++--------- src/Mapper/SuffixMapper.php | 21 +++++++++------------ src/Name.php | 4 ++-- src/Parser.php | 27 +++++++++------------------ src/Part/AbstractPart.php | 21 +++++++++------------ src/Part/Initial.php | 1 + src/Part/LastnamePrefix.php | 3 ++- src/Part/NamePart.php | 1 + src/Part/Nickname.php | 1 + src/Part/PreNormalizedPart.php | 3 ++- 17 files changed, 77 insertions(+), 94 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 7e70781..bf690a8 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -15,6 +15,11 @@ 'array_syntax' => ['syntax' => 'short'], 'blank_line_after_namespace' => true, 'no_extra_blank_lines' => true, + 'phpdoc_line_span' => [ + 'property' => 'multi', + 'method' => 'multi', + 'const' => 'multi', + ], ]) ->setFinder($finder) ->setCacheFile(__DIR__.'/.php-cs-fixer.cache'); diff --git a/src/Mapper/AbstractMapper.php b/src/Mapper/AbstractMapper.php index 3cd566a..d1b0161 100644 --- a/src/Mapper/AbstractMapper.php +++ b/src/Mapper/AbstractMapper.php @@ -8,16 +8,13 @@ abstract class AbstractMapper { /** * implements the mapping of parts - * - * @param array $parts - the name parts - * @return array $parts - the mapped parts */ - abstract public function map(array $parts); + abstract public function map(array $parts): array; /** * checks if there are still unmapped parts left before the given position */ - protected function hasUnmappedPartsBefore(array $parts, $index): bool + protected function hasUnmappedPartsBefore(array $parts, int $index): bool { foreach ($parts as $k => $part) { if ($k === $index) { @@ -32,10 +29,7 @@ protected function hasUnmappedPartsBefore(array $parts, $index): bool return false; } - /** - * @return int|bool - */ - protected function findFirstMapped(string $type, array $parts) + protected function findFirstMapped(string $type, array $parts): int|false { $total = count($parts); @@ -50,11 +44,8 @@ protected function findFirstMapped(string $type, array $parts) /** * get the registry lookup key for the given word - * - * @param string $word the word - * @return string the key */ - protected function getKey($word): string + protected function getKey(string $word): string { return strtolower(str_replace('.', '', $word)); } diff --git a/src/Mapper/FirstnameMapper.php b/src/Mapper/FirstnameMapper.php index 2d4cbf1..6eade79 100644 --- a/src/Mapper/FirstnameMapper.php +++ b/src/Mapper/FirstnameMapper.php @@ -16,6 +16,7 @@ class FirstnameMapper extends AbstractMapper * @param array $parts the parts * @return array the mapped parts */ + #[\Override] public function map(array $parts): array { if (count($parts) < 2) { diff --git a/src/Mapper/InitialMapper.php b/src/Mapper/InitialMapper.php index 45f2098..769889c 100644 --- a/src/Mapper/InitialMapper.php +++ b/src/Mapper/InitialMapper.php @@ -10,15 +10,10 @@ */ class InitialMapper extends AbstractMapper { - protected $matchLastPart = false; - - private $combinedMax = 2; - - public function __construct(int $combinedMax = 2, bool $matchLastPart = false) - { - $this->matchLastPart = $matchLastPart; - $this->combinedMax = $combinedMax; - } + public function __construct( + private int $combinedMax = 2, + protected bool $matchLastPart = false, + ) {} /** * map intials in parts array @@ -26,6 +21,7 @@ public function __construct(int $combinedMax = 2, bool $matchLastPart = false) * @param array $parts the name parts * @return array the mapped parts */ + #[\Override] public function map(array $parts): array { $last = count($parts) - 1; diff --git a/src/Mapper/LastnameMapper.php b/src/Mapper/LastnameMapper.php index ce30aab..1332344 100644 --- a/src/Mapper/LastnameMapper.php +++ b/src/Mapper/LastnameMapper.php @@ -11,15 +11,13 @@ class LastnameMapper extends AbstractMapper { - protected $prefixes = []; - - protected $matchSinglePart = false; - - public function __construct(array $prefixes, bool $matchSinglePart = false) - { - $this->prefixes = $prefixes; - $this->matchSinglePart = $matchSinglePart; - } + /** + * @param array $prefixes + */ + public function __construct( + protected array $prefixes, + protected bool $matchSinglePart = false, + ) {} /** * map lastnames in the parts array @@ -27,6 +25,7 @@ public function __construct(array $prefixes, bool $matchSinglePart = false) * @param array $parts the name parts * @return array the mapped parts */ + #[\Override] public function map(array $parts): array { if (! $this->matchSinglePart && count($parts) < 2) { diff --git a/src/Mapper/MiddlenameMapper.php b/src/Mapper/MiddlenameMapper.php index 822807a..05042fa 100644 --- a/src/Mapper/MiddlenameMapper.php +++ b/src/Mapper/MiddlenameMapper.php @@ -9,12 +9,9 @@ class MiddlenameMapper extends AbstractMapper { - protected $mapWithoutLastname = false; - - public function __construct(bool $mapWithoutLastname = false) - { - $this->mapWithoutLastname = $mapWithoutLastname; - } + public function __construct( + protected bool $mapWithoutLastname = false, + ) {} /** * map middlenames in the parts array @@ -22,6 +19,7 @@ public function __construct(bool $mapWithoutLastname = false) * @param array $parts the name parts * @return array the mapped parts */ + #[\Override] public function map(array $parts): array { // If we don't expect a lastname, match a mimimum of 2 parts diff --git a/src/Mapper/NicknameMapper.php b/src/Mapper/NicknameMapper.php index 49b36ab..adc1592 100644 --- a/src/Mapper/NicknameMapper.php +++ b/src/Mapper/NicknameMapper.php @@ -8,9 +8,9 @@ class NicknameMapper extends AbstractMapper { /** - * @var array + * @var array */ - protected $delimiters = [ + protected array $delimiters = [ '[' => ']', '{' => '}', '(' => ')', @@ -19,6 +19,9 @@ class NicknameMapper extends AbstractMapper '\'' => '\'', ]; + /** + * @param array $delimiters + */ public function __construct(array $delimiters = []) { if (! empty($delimiters)) { @@ -32,6 +35,7 @@ public function __construct(array $delimiters = []) * @param array $parts the name parts * @return array the mapped parts */ + #[\Override] public function map(array $parts): array { $isEncapsulated = false; diff --git a/src/Mapper/SalutationMapper.php b/src/Mapper/SalutationMapper.php index fa144c0..7c19d6e 100644 --- a/src/Mapper/SalutationMapper.php +++ b/src/Mapper/SalutationMapper.php @@ -7,15 +7,13 @@ class SalutationMapper extends AbstractMapper { - protected $salutations = []; - - protected $maxIndex = 0; - - public function __construct(array $salutations, $maxIndex = 0) - { - $this->salutations = $salutations; - $this->maxIndex = $maxIndex; - } + /** + * @param array $salutations + */ + public function __construct( + protected array $salutations, + protected int $maxIndex = 0, + ) {} /** * map salutations in the parts array @@ -23,6 +21,7 @@ public function __construct(array $salutations, $maxIndex = 0) * @param array $parts the name parts * @return array the mapped parts */ + #[\Override] public function map(array $parts): array { $max = ($this->maxIndex > 0) ? $this->maxIndex : floor(count($parts) / 2); diff --git a/src/Mapper/SuffixMapper.php b/src/Mapper/SuffixMapper.php index a40f627..5b14f2c 100644 --- a/src/Mapper/SuffixMapper.php +++ b/src/Mapper/SuffixMapper.php @@ -7,18 +7,14 @@ class SuffixMapper extends AbstractMapper { - protected $suffixes = []; - - protected $matchSinglePart = false; - - protected $reservedParts = 2; - - public function __construct(array $suffixes, bool $matchSinglePart = false, int $reservedParts = 2) - { - $this->suffixes = $suffixes; - $this->matchSinglePart = $matchSinglePart; - $this->reservedParts = $reservedParts; - } + /** + * @param array $suffixes + */ + public function __construct( + protected array $suffixes, + protected bool $matchSinglePart = false, + protected int $reservedParts = 2, + ) {} /** * map suffixes in the parts array @@ -26,6 +22,7 @@ public function __construct(array $suffixes, bool $matchSinglePart = false, int * @param array $parts the name parts * @return array the mapped parts */ + #[\Override] public function map(array $parts): array { if ($this->isMatchingSinglePart($parts)) { diff --git a/src/Name.php b/src/Name.php index 149679e..089d40a 100644 --- a/src/Name.php +++ b/src/Name.php @@ -9,9 +9,9 @@ class Name private const PARTS_NAMESPACE = 'CodeByZach\NameParser\Part'; /** - * @var array the parts that make up this name + * @var list the parts that make up this name */ - protected $parts = []; + protected array $parts = []; /** * constructor takes the array of parts this name consists of diff --git a/src/Parser.php b/src/Parser.php index b457bc9..8338529 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -13,35 +13,26 @@ class Parser { - /** - * @var string - */ - protected $whitespace = " \r\n\t"; + protected string $whitespace = " \r\n\t"; /** - * @var array + * @var list<\CodeByZach\NameParser\Mapper\AbstractMapper> */ - protected $mappers = []; + protected array $mappers = []; /** - * @var array + * @var list */ - protected $languages = []; + protected array $languages = []; /** - * @var array + * @var array */ - protected $nicknameDelimiters = []; + protected array $nicknameDelimiters = []; - /** - * @var int - */ - protected $maxSalutationIndex = 0; + protected int $maxSalutationIndex = 0; - /** - * @var int - */ - protected $maxCombinedInitials = 2; + protected int $maxCombinedInitials = 2; public function __construct(array $languages = []) { diff --git a/src/Part/AbstractPart.php b/src/Part/AbstractPart.php index 21e9b2f..f1cf604 100644 --- a/src/Part/AbstractPart.php +++ b/src/Part/AbstractPart.php @@ -5,14 +5,14 @@ abstract class AbstractPart { /** - * @var string the wrapped value + * the wrapped value */ - protected $value; + protected string $value = ''; /** * constructor allows passing the value to wrap */ - public function __construct($value) + public function __construct(string|AbstractPart $value) { $this->setValue($value); } @@ -20,11 +20,8 @@ public function __construct($value) /** * set the value to wrap * (can take string or part instance) - * - * @param string|AbstractPart $value - * @return $this */ - public function setValue($value): AbstractPart + public function setValue(string|AbstractPart $value): static { if ($value instanceof AbstractPart) { $value = $value->getValue(); @@ -54,22 +51,22 @@ public function normalize(): string /** * helper for camelization of values * to be used during normalize - * - * @param string $word */ - protected function camelcase($word): string + protected function camelcase(string $word): string { if (preg_match('/\p{L}(\p{Lu}*\p{Ll}\p{Ll}*\p{Lu}|\p{Ll}*\p{Lu}\p{Lu}*\p{Ll})\p{L}*/u', $word)) { return $word; } - return preg_replace_callback('/[\p{L}0-9]+/ui', [$this, 'camelcaseReplace'], $word); + return preg_replace_callback('/[\p{L}0-9]+/ui', $this->camelcaseReplace(...), $word); } /** * camelcasing callback + * + * @param array $matches */ - protected function camelcaseReplace($matches): string + protected function camelcaseReplace(array $matches): string { if (function_exists('mb_convert_case')) { return mb_convert_case($matches[0], MB_CASE_TITLE, 'UTF-8'); diff --git a/src/Part/Initial.php b/src/Part/Initial.php index 8f2b081..0959681 100644 --- a/src/Part/Initial.php +++ b/src/Part/Initial.php @@ -7,6 +7,7 @@ class Initial extends GivenNamePart /** * uppercase the initial */ + #[\Override] public function normalize(): string { return strtoupper($this->getValue()); diff --git a/src/Part/LastnamePrefix.php b/src/Part/LastnamePrefix.php index e099677..9589be0 100644 --- a/src/Part/LastnamePrefix.php +++ b/src/Part/LastnamePrefix.php @@ -4,7 +4,7 @@ class LastnamePrefix extends Lastname { - protected $normalized = ''; + protected string $normalized; public function __construct(string $value, ?string $normalized = null) { @@ -17,6 +17,7 @@ public function __construct(string $value, ?string $normalized = null) * if this is a lastname prefix, look up normalized version from registry * otherwise camelcase the lastname */ + #[\Override] public function normalize(): string { return $this->normalized; diff --git a/src/Part/NamePart.php b/src/Part/NamePart.php index 349727f..7334f8e 100644 --- a/src/Part/NamePart.php +++ b/src/Part/NamePart.php @@ -7,6 +7,7 @@ abstract class NamePart extends AbstractPart /** * camelcase the lastname */ + #[\Override] public function normalize(): string { return $this->camelcase($this->getValue()); diff --git a/src/Part/Nickname.php b/src/Part/Nickname.php index 9faa168..c7425f6 100644 --- a/src/Part/Nickname.php +++ b/src/Part/Nickname.php @@ -7,6 +7,7 @@ class Nickname extends AbstractPart /** * camelcase the nickname for normalization */ + #[\Override] public function normalize(): string { return $this->camelcase($this->getValue()); diff --git a/src/Part/PreNormalizedPart.php b/src/Part/PreNormalizedPart.php index c7a6ed5..395bc9d 100644 --- a/src/Part/PreNormalizedPart.php +++ b/src/Part/PreNormalizedPart.php @@ -4,7 +4,7 @@ abstract class PreNormalizedPart extends AbstractPart { - protected $normalized = ''; + protected string $normalized; public function __construct(string $value, ?string $normalized = null) { @@ -17,6 +17,7 @@ public function __construct(string $value, ?string $normalized = null) * if this is a lastname prefix, look up normalized version from registry * otherwise camelcase the lastname */ + #[\Override] public function normalize(): string { return $this->normalized; From 64290c8e4a26f0ba46e138fbca023491d8e4c50d Mon Sep 17 00:00:00 2001 From: Zachary Miller Date: Sun, 10 May 2026 17:47:49 -0400 Subject: [PATCH 11/14] Phase 3d cont.: Reach PHPStan level 9 (full type annotations) Bump phpstan.neon.dist level from 5 to 9 (highest practical level short of bleeding-edge level 10, which targets brand-new generic features). Real bugs caught and fixed by stricter analysis: - Parser::normalize: preg_replace() can return null on regex error; was being assigned to a string return type. Added ?? \$name fallback. - AbstractPart::camelcase: same fix for preg_replace_callback() null return path. Type annotations added throughout (75+ docblock additions): - LanguageInterface and concrete English/German: every getter declares its return as array (lookup-key => display-form) - AbstractMapper and concrete mappers: \$parts annotated as array; helper methods get \$type as class-string, \$index as int, etc. - LastnameMapper: tightened internal helper signatures, added is_string() narrowing where the union type leaked through helpers, removed redundant @param/@return tags now that types are native - SalutationMapper: isMatchingSubset() gets a @phpstan-assert-if-true array annotation so PHPStan knows the post-check narrowing on \$subset - SuffixMapper: isSuffix() declared with AbstractPart|string param + @phpstan-assert-if-true string annotation (returns true only when the input is a string suffix candidate) - InitialMapper: added is_string() guard before isInitial() now that \$part is typed as the union - Name: \$parts property + setParts/getParts/__construct typed with array; getAll() returns array - Parser: \$languages typed array; \$mappers typed array; getPrefixes/getSuffixes/getSalutations return array; setWhitespace param typed as string; parseSplitName params typed as string Test annotations: - All test methods get : void return type (PHPUnit convention; PHPStan level 7+ requires it) - Data providers get @return array> (Mapper tests) or array}> (parser tests) - testParse(string \$input, array \$expectation) - typed inputs - AbstractMapperTestCase::testMap typed parameters, replaced call_user_func_array with first-class callable spread (\$this->getMapper(...\$arguments)) - AbstractMapperTestCase::getMapper now declared as returning AbstractMapper; concrete subclasses declare their specific mapper return type (e.g., FirstnameMapper) Type system change: list -> array: - list requires consecutive 0-indexed keys, which PHPStan can't prove after \$parts[\$k] = \$value reassignment (even though it's semantically a replacement, not a sparse insert). array is slightly less precise but eliminates 25+ false-positive return-type errors without weakening real safety. Test suite still: 131 tests, 235 assertions, 0 errors/warnings/deprecations. PHPStan level 9: 0 errors. PHP-CS-Fixer: 0 fixable. --- phpstan.neon.dist | 2 +- src/Language/English.php | 12 ++++++ src/Language/German.php | 12 ++++++ src/LanguageInterface.php | 9 +++++ src/Mapper/AbstractMapper.php | 9 +++++ src/Mapper/FirstnameMapper.php | 15 +++++--- src/Mapper/InitialMapper.php | 6 +-- src/Mapper/LastnameMapper.php | 51 +++++++++++++++++-------- src/Mapper/MiddlenameMapper.php | 10 ++--- src/Mapper/NicknameMapper.php | 9 ++--- src/Mapper/SalutationMapper.php | 25 ++++++++---- src/Mapper/SuffixMapper.php | 20 +++++++--- src/Name.php | 14 ++++++- src/Parser.php | 45 ++++++++++++---------- src/Part/AbstractPart.php | 2 +- tests/GermanParserTest.php | 9 +++-- tests/Mapper/AbstractMapperTestCase.php | 13 +++++-- tests/Mapper/FirstnameMapperTest.php | 6 +-- tests/Mapper/InitialMapperTest.php | 6 +-- tests/Mapper/LastnameMapperTest.php | 6 +-- tests/Mapper/MiddlenameMapperTest.php | 6 +-- tests/Mapper/NicknameMapperTest.php | 6 +-- tests/Mapper/SalutationMapperTest.php | 6 +-- tests/Mapper/SuffixMapperTest.php | 6 +-- tests/NameTest.php | 6 +-- tests/ParserTest.php | 19 +++++---- tests/Part/AbstractPartTest.php | 4 +- tests/Part/NormalisationTest.php | 4 +- 28 files changed, 224 insertions(+), 114 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index c5c0405..d4e24ef 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - level: 5 + level: 9 paths: - src - tests diff --git a/src/Language/English.php b/src/Language/English.php index 9b65aa1..d2b8893 100644 --- a/src/Language/English.php +++ b/src/Language/English.php @@ -94,16 +94,28 @@ class English implements LanguageInterface 'von' => 'von', ]; + /** + * @return array + */ + #[\Override] public function getSuffixes(): array { return self::SUFFIXES; } + /** + * @return array + */ + #[\Override] public function getSalutations(): array { return self::SALUTATIONS; } + /** + * @return array + */ + #[\Override] public function getLastnamePrefixes(): array { return self::LASTNAME_PREFIXES; diff --git a/src/Language/German.php b/src/Language/German.php index 263b26e..499a09e 100644 --- a/src/Language/German.php +++ b/src/Language/German.php @@ -31,16 +31,28 @@ class German implements LanguageInterface 'von' => 'von', ]; + /** + * @return array + */ + #[\Override] public function getSuffixes(): array { return self::SUFFIXES; } + /** + * @return array + */ + #[\Override] public function getSalutations(): array { return self::SALUTATIONS; } + /** + * @return array + */ + #[\Override] public function getLastnamePrefixes(): array { return self::LASTNAME_PREFIXES; diff --git a/src/LanguageInterface.php b/src/LanguageInterface.php index c7e64f5..7d74afa 100644 --- a/src/LanguageInterface.php +++ b/src/LanguageInterface.php @@ -4,9 +4,18 @@ interface LanguageInterface { + /** + * @return array + */ public function getSuffixes(): array; + /** + * @return array + */ public function getLastnamePrefixes(): array; + /** + * @return array + */ public function getSalutations(): array; } diff --git a/src/Mapper/AbstractMapper.php b/src/Mapper/AbstractMapper.php index d1b0161..418f84a 100644 --- a/src/Mapper/AbstractMapper.php +++ b/src/Mapper/AbstractMapper.php @@ -8,11 +8,16 @@ abstract class AbstractMapper { /** * implements the mapping of parts + * + * @param array $parts + * @return array */ abstract public function map(array $parts): array; /** * checks if there are still unmapped parts left before the given position + * + * @param array $parts */ protected function hasUnmappedPartsBefore(array $parts, int $index): bool { @@ -29,6 +34,10 @@ protected function hasUnmappedPartsBefore(array $parts, int $index): bool return false; } + /** + * @param class-string $type + * @param array $parts + */ protected function findFirstMapped(string $type, array $parts): int|false { $total = count($parts); diff --git a/src/Mapper/FirstnameMapper.php b/src/Mapper/FirstnameMapper.php index 6eade79..0f6f234 100644 --- a/src/Mapper/FirstnameMapper.php +++ b/src/Mapper/FirstnameMapper.php @@ -13,8 +13,8 @@ class FirstnameMapper extends AbstractMapper /** * map firstnames in parts array * - * @param array $parts the parts - * @return array the mapped parts + * @param array $parts + * @return array */ #[\Override] public function map(array $parts): array @@ -32,10 +32,7 @@ public function map(array $parts): array return $parts; } - /** - * @param string|AbstractPart $part - */ - protected function handleSinglePart($part): AbstractPart + protected function handleSinglePart(string|AbstractPart $part): AbstractPart { if ($part instanceof AbstractPart) { return $part; @@ -44,6 +41,9 @@ protected function handleSinglePart($part): AbstractPart return new Firstname($part); } + /** + * @param array $parts + */ protected function findFirstnamePosition(array $parts): ?int { $pos = null; @@ -72,6 +72,9 @@ protected function findFirstnamePosition(array $parts): ?int return $pos; } + /** + * @param array $parts + */ protected function getStartIndex(array $parts): int { $index = $this->findFirstMapped(Salutation::class, $parts); diff --git a/src/Mapper/InitialMapper.php b/src/Mapper/InitialMapper.php index 769889c..5268dba 100644 --- a/src/Mapper/InitialMapper.php +++ b/src/Mapper/InitialMapper.php @@ -18,8 +18,8 @@ public function __construct( /** * map intials in parts array * - * @param array $parts the name parts - * @return array the mapped parts + * @param array $parts + * @return array */ #[\Override] public function map(array $parts): array @@ -48,7 +48,7 @@ public function map(array $parts): array } } - if ($this->isInitial($part)) { + if (is_string($part) && $this->isInitial($part)) { $parts[$k] = new Initial($part); } } diff --git a/src/Mapper/LastnameMapper.php b/src/Mapper/LastnameMapper.php index 1332344..3d8d4d1 100644 --- a/src/Mapper/LastnameMapper.php +++ b/src/Mapper/LastnameMapper.php @@ -22,8 +22,8 @@ public function __construct( /** * map lastnames in the parts array * - * @param array $parts the name parts - * @return array the mapped parts + * @param array $parts + * @return array */ #[\Override] public function map(array $parts): array @@ -38,6 +38,9 @@ public function map(array $parts): array /** * we map the parts in reverse order because it makes more * sense to parse for the lastname starting from the end + * + * @param array $parts + * @return array */ protected function mapParts(array $parts): array { @@ -77,15 +80,23 @@ protected function mapParts(array $parts): array /** * try to map this part as a lastname prefix or as a combined * lastname part containing a prefix + * + * @param array $parts */ private function mapAsPrefixIfPossible(array $parts, int $k): ?Lastname { + $part = $parts[$k]; + + if (! is_string($part)) { + return null; + } + if ($this->isApplicablePrefix($parts, $k)) { - return new LastnamePrefix($parts[$k], $this->prefixes[$this->getKey($parts[$k])]); + return new LastnamePrefix($part, $this->prefixes[$this->getKey($part)]); } - if ($this->isCombinedWithPrefix($parts[$k])) { - return new Lastname($parts[$k]); + if ($this->isCombinedWithPrefix($part)) { + return new Lastname($part); } return null; @@ -108,6 +119,8 @@ private function isCombinedWithPrefix(string $part): bool /** * skip through the parts we want to ignore and return the start index + * + * @param array $parts */ protected function skipIgnoredParts(array $parts): int { @@ -127,6 +140,8 @@ protected function skipIgnoredParts(array $parts): int * * the assumption is that lastname parts have already been found * but we want to see if we should add more parts + * + * @param array $parts */ protected function shouldStopMapping(array $parts, int $k): bool { @@ -140,15 +155,13 @@ protected function shouldStopMapping(array $parts, int $k): bool return true; } - return strlen($lastPart->getValue()) >= 3; + return $lastPart instanceof AbstractPart && strlen($lastPart->getValue()) >= 3; } /** * indicates if the given part should be ignored (skipped) during mapping - * - * @return bool */ - protected function isIgnoredPart($part) + protected function isIgnoredPart(AbstractPart|string $part): bool { return $part instanceof Suffix || $part instanceof Nickname || $part instanceof Salutation; } @@ -158,6 +171,9 @@ protected function isIgnoredPart($part) * * if the mapping did not derive any lastname this is called to transform * any previously ignored parts into lastname parts + * + * @param array $parts + * @return array */ protected function remapIgnored(array $parts): array { @@ -176,6 +192,9 @@ protected function remapIgnored(array $parts): array return $parts; } + /** + * @param array $parts + */ protected function isFollowedByLastnamePart(array $parts, int $index): bool { $next = $this->skipNicknameParts($parts, $index + 1); @@ -192,10 +211,14 @@ protected function isFollowedByLastnamePart(array $parts, int $index): bool * the name (this effectively prioritises firstname over prefix matching). * * This expects the parts array and index to be in the original order. + * + * @param array $parts */ protected function isApplicablePrefix(array $parts, int $index): bool { - if (! $this->isPrefix($parts[$index])) { + $part = $parts[$index]; + + if (! is_string($part) || ! $this->isPrefix($part)) { return false; } @@ -204,10 +227,8 @@ protected function isApplicablePrefix(array $parts, int $index): bool /** * check if the given word is a lastname prefix - * - * @param string $word the word to check */ - protected function isPrefix($word): bool + protected function isPrefix(string $word): bool { return array_key_exists($this->getKey($word), $this->prefixes); } @@ -215,9 +236,9 @@ protected function isPrefix($word): bool /** * find the next non-nickname index in parts * - * @return int|void + * @param array $parts */ - protected function skipNicknameParts($parts, $startIndex) + protected function skipNicknameParts(array $parts, int $startIndex): int { $total = count($parts); diff --git a/src/Mapper/MiddlenameMapper.php b/src/Mapper/MiddlenameMapper.php index 05042fa..4bdd309 100644 --- a/src/Mapper/MiddlenameMapper.php +++ b/src/Mapper/MiddlenameMapper.php @@ -16,8 +16,8 @@ public function __construct( /** * map middlenames in the parts array * - * @param array $parts the name parts - * @return array the mapped parts + * @param array $parts + * @return array */ #[\Override] public function map(array $parts): array @@ -39,10 +39,10 @@ public function map(array $parts): array } /** - * @param int $start - * @param array $parts + * @param array $parts + * @return array */ - protected function mapFrom($start, $parts): array + protected function mapFrom(int $start, array $parts): array { // If we don't expect a lastname, include the last part, // otherwise skip the last (-1) because it should be a lastname diff --git a/src/Mapper/NicknameMapper.php b/src/Mapper/NicknameMapper.php index adc1592..b5e2bc8 100644 --- a/src/Mapper/NicknameMapper.php +++ b/src/Mapper/NicknameMapper.php @@ -32,8 +32,8 @@ public function __construct(array $delimiters = []) /** * map nicknames in the parts array * - * @param array $parts the name parts - * @return array the mapped parts + * @param array $parts + * @return array */ #[\Override] public function map(array $parts): array @@ -70,10 +70,7 @@ public function map(array $parts): array return $parts; } - /** - * @return string - */ - protected function buildRegexp() + protected function buildRegexp(): string { $regexp = '/^(['; diff --git a/src/Mapper/SalutationMapper.php b/src/Mapper/SalutationMapper.php index 7c19d6e..8751212 100644 --- a/src/Mapper/SalutationMapper.php +++ b/src/Mapper/SalutationMapper.php @@ -18,8 +18,8 @@ public function __construct( /** * map salutations in the parts array * - * @param array $parts the name parts - * @return array the mapped parts + * @param array $parts + * @return array */ #[\Override] public function map(array $parts): array @@ -41,11 +41,16 @@ public function map(array $parts): array * We pass the full parts array and the current position to allow * not only single-word matches but also combined matches with * subsequent words (parts). + * + * @param array $parts + * @return array */ protected function substituteWithSalutation(array $parts, int $start): array { - if ($this->isSalutation($parts[$start])) { - $parts[$start] = new Salutation($parts[$start], $this->salutations[$this->getKey($parts[$start])]); + $current = $parts[$start]; + + if (is_string($current) && $this->isSalutation($current)) { + $parts[$start] = new Salutation($current, $this->salutations[$this->getKey($current)]); return $parts; } @@ -70,11 +75,17 @@ protected function substituteWithSalutation(array $parts, int $start): array * check if the given subset matches the given keys entry by entry, * which means word by word, except that we first need to key-ify * the subset words + * + * @param array $keys + * @param array $subset + * + * @phpstan-assert-if-true array $subset */ private function isMatchingSubset(array $keys, array $subset): bool { for ($i = 0; $i < count($subset); $i++) { - if ($this->getKey($subset[$i]) !== $keys[$i]) { + $part = $subset[$i]; + if (! is_string($part) || $this->getKey($part) !== $keys[$i]) { return false; } } @@ -84,10 +95,8 @@ private function isMatchingSubset(array $keys, array $subset): bool /** * check if the given word is a viable salutation - * - * @param string $word the word to check */ - protected function isSalutation($word): bool + protected function isSalutation(string $word): bool { return array_key_exists($this->getKey($word), $this->salutations); } diff --git a/src/Mapper/SuffixMapper.php b/src/Mapper/SuffixMapper.php index 5b14f2c..f3d6c4d 100644 --- a/src/Mapper/SuffixMapper.php +++ b/src/Mapper/SuffixMapper.php @@ -19,14 +19,17 @@ public function __construct( /** * map suffixes in the parts array * - * @param array $parts the name parts - * @return array the mapped parts + * @param array $parts + * @return array */ #[\Override] public function map(array $parts): array { if ($this->isMatchingSinglePart($parts)) { - $parts[0] = new Suffix($parts[0], $this->suffixes[$this->getKey($parts[0])]); + $first = $parts[0]; + if (is_string($first)) { + $parts[0] = new Suffix($first, $this->suffixes[$this->getKey($first)]); + } return $parts; } @@ -40,13 +43,17 @@ public function map(array $parts): array break; } + // isSuffix() guarantees $part is a string at this point $parts[$k] = new Suffix($part, $this->suffixes[$this->getKey($part)]); } return $parts; } - protected function isMatchingSinglePart($parts): bool + /** + * @param array $parts + */ + protected function isMatchingSinglePart(array $parts): bool { if (! $this->matchSinglePart) { return false; @@ -59,7 +66,10 @@ protected function isMatchingSinglePart($parts): bool return $this->isSuffix($parts[0]); } - protected function isSuffix($part): bool + /** + * @phpstan-assert-if-true string $part + */ + protected function isSuffix(AbstractPart|string $part): bool { if ($part instanceof AbstractPart) { return false; diff --git a/src/Name.php b/src/Name.php index 089d40a..e7d804a 100644 --- a/src/Name.php +++ b/src/Name.php @@ -9,12 +9,14 @@ class Name private const PARTS_NAMESPACE = 'CodeByZach\NameParser\Part'; /** - * @var list the parts that make up this name + * @var array the parts that make up this name */ protected array $parts = []; /** * constructor takes the array of parts this name consists of + * + * @param array|null $parts */ public function __construct(?array $parts = null) { @@ -31,6 +33,7 @@ public function __toString(): string /** * set the parts this name consists of * + * @param array $parts * @return $this */ public function setParts(array $parts): Name @@ -42,12 +45,17 @@ public function setParts(array $parts): Name /** * get the parts this name consists of + * + * @return array */ public function getParts(): array { return $this->parts; } + /** + * @return array + */ public function getAll(bool $format = false): array { $results = []; @@ -63,7 +71,9 @@ public function getAll(bool $format = false): array foreach ($keys as $key => $args) { $method = sprintf('get%s', ucfirst($key)); - if ($value = call_user_func_array([$this, $method], $args)) { + /** @var callable(): string $callable */ + $callable = [$this, $method]; + if ($value = $callable(...$args)) { $results[$key] = $value; } } diff --git a/src/Parser.php b/src/Parser.php index 8338529..2064167 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -16,12 +16,12 @@ class Parser protected string $whitespace = " \r\n\t"; /** - * @var list<\CodeByZach\NameParser\Mapper\AbstractMapper> + * @var array */ protected array $mappers = []; /** - * @var list + * @var array */ protected array $languages = []; @@ -34,6 +34,9 @@ class Parser protected int $maxCombinedInitials = 2; + /** + * @param array $languages + */ public function __construct(array $languages = []) { if (empty($languages)) { @@ -50,10 +53,8 @@ public function __construct(array $languages = []) * - middle initials * - surname / last name * - suffix (II, Phd, Jr, etc) - * - * @param string $name */ - public function parse($name): Name + public function parse(string $name): Name { $name = $this->normalize($name); @@ -74,11 +75,8 @@ public function parse($name): Name /** * handles split-parsing of comma-separated name parts - * - * @param $left - the name part left of the comma - * @param $right - the name part right of the comma */ - protected function parseSplitName($first, $second, $third): Name + protected function parseSplitName(string $first, string $second, string $third): Name { $parts = array_merge( $this->getFirstSegmentParser()->parse($first)->getParts(), @@ -133,6 +131,8 @@ protected function getThirdSegmentParser(): Parser /** * get the mappers for this parser + * + * @return array */ public function getMappers(): array { @@ -153,6 +153,8 @@ public function getMappers(): array /** * set the mappers for this parser + * + * @param array $mappers */ public function setMappers(array $mappers): Parser { @@ -170,7 +172,7 @@ protected function normalize(string $name): string $name = trim($name); - return preg_replace('/[' . preg_quote($whitespace, '/') . ']+/', ' ', $name); + return preg_replace('/[' . preg_quote($whitespace, '/') . ']+/', ' ', $name) ?? $name; } /** @@ -184,7 +186,7 @@ public function getWhitespace(): string /** * set the string of characters that are supposed to be treated as whitespace */ - public function setWhitespace($whitespace): Parser + public function setWhitespace(string $whitespace): Parser { $this->whitespace = $whitespace; @@ -192,13 +194,12 @@ public function setWhitespace($whitespace): Parser } /** - * @return array + * @return array */ - protected function getPrefixes() + protected function getPrefixes(): array { $prefixes = []; - /** @var LanguageInterface $language */ foreach ($this->languages as $language) { $prefixes += $language->getLastnamePrefixes(); } @@ -207,13 +208,12 @@ protected function getPrefixes() } /** - * @return array + * @return array */ - protected function getSuffixes() + protected function getSuffixes(): array { $suffixes = []; - /** @var LanguageInterface $language */ foreach ($this->languages as $language) { $suffixes += $language->getSuffixes(); } @@ -222,13 +222,12 @@ protected function getSuffixes() } /** - * @return array + * @return array */ - protected function getSalutations() + protected function getSalutations(): array { $salutations = []; - /** @var LanguageInterface $language */ foreach ($this->languages as $language) { $salutations += $language->getSalutations(); } @@ -236,11 +235,17 @@ protected function getSalutations() return $salutations; } + /** + * @return array + */ public function getNicknameDelimiters(): array { return $this->nicknameDelimiters; } + /** + * @param array $nicknameDelimiters + */ public function setNicknameDelimiters(array $nicknameDelimiters): Parser { $this->nicknameDelimiters = $nicknameDelimiters; diff --git a/src/Part/AbstractPart.php b/src/Part/AbstractPart.php index f1cf604..28b9455 100644 --- a/src/Part/AbstractPart.php +++ b/src/Part/AbstractPart.php @@ -58,7 +58,7 @@ protected function camelcase(string $word): string return $word; } - return preg_replace_callback('/[\p{L}0-9]+/ui', $this->camelcaseReplace(...), $word); + return preg_replace_callback('/[\p{L}0-9]+/ui', $this->camelcaseReplace(...), $word) ?? $word; } /** diff --git a/tests/GermanParserTest.php b/tests/GermanParserTest.php index 57ceca2..2850847 100644 --- a/tests/GermanParserTest.php +++ b/tests/GermanParserTest.php @@ -11,9 +11,9 @@ class GermanParserTest extends TestCase { /** - * @return array + * @return array}> */ - public static function provider() + public static function provider(): array { return [ [ @@ -50,8 +50,11 @@ public static function provider() ]; } + /** + * @param array $expectation + */ #[DataProvider('provider')] - public function testParse($input, $expectation) + public function testParse(string $input, array $expectation): void { $parser = new Parser([ new German(), diff --git a/tests/Mapper/AbstractMapperTestCase.php b/tests/Mapper/AbstractMapperTestCase.php index 4dac4af..ea6c4db 100644 --- a/tests/Mapper/AbstractMapperTestCase.php +++ b/tests/Mapper/AbstractMapperTestCase.php @@ -2,18 +2,25 @@ namespace Tests\CodeByZach\NameParser\Mapper; +use CodeByZach\NameParser\Mapper\AbstractMapper; +use CodeByZach\NameParser\Part\AbstractPart; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; abstract class AbstractMapperTestCase extends TestCase { + /** + * @param array $input + * @param array $expectation + * @param array $arguments + */ #[DataProvider('provider')] - public function testMap($input, $expectation, $arguments = []) + public function testMap(array $input, array $expectation, array $arguments = []): void { - $mapper = call_user_func_array([$this, 'getMapper'], $arguments); + $mapper = $this->getMapper(...$arguments); $this->assertEquals($expectation, $mapper->map($input)); } - abstract protected function getMapper(); + abstract protected function getMapper(): AbstractMapper; } diff --git a/tests/Mapper/FirstnameMapperTest.php b/tests/Mapper/FirstnameMapperTest.php index f8d8c6b..92fd790 100644 --- a/tests/Mapper/FirstnameMapperTest.php +++ b/tests/Mapper/FirstnameMapperTest.php @@ -10,9 +10,9 @@ class FirstnameMapperTest extends AbstractMapperTestCase { /** - * @return array + * @return array> */ - public static function provider() + public static function provider(): array { return [ [ @@ -62,7 +62,7 @@ public static function provider() ]; } - protected function getMapper() + protected function getMapper(): FirstnameMapper { return new FirstnameMapper(); } diff --git a/tests/Mapper/InitialMapperTest.php b/tests/Mapper/InitialMapperTest.php index 9fb5ea7..af7f7ac 100644 --- a/tests/Mapper/InitialMapperTest.php +++ b/tests/Mapper/InitialMapperTest.php @@ -10,9 +10,9 @@ class InitialMapperTest extends AbstractMapperTestCase { /** - * @return array + * @return array> */ - public static function provider() + public static function provider(): array { return [ [ @@ -102,7 +102,7 @@ public static function provider() ]; } - protected function getMapper($maxCombined = 2, $matchLastPart = false) + protected function getMapper(int $maxCombined = 2, bool $matchLastPart = false): InitialMapper { return new InitialMapper($maxCombined, $matchLastPart); } diff --git a/tests/Mapper/LastnameMapperTest.php b/tests/Mapper/LastnameMapperTest.php index 3fc5903..60235a2 100644 --- a/tests/Mapper/LastnameMapperTest.php +++ b/tests/Mapper/LastnameMapperTest.php @@ -12,9 +12,9 @@ class LastnameMapperTest extends AbstractMapperTestCase { /** - * @return array + * @return array> */ - public static function provider() + public static function provider(): array { return [ [ @@ -119,7 +119,7 @@ public static function provider() ]; } - protected function getMapper($matchSingle = false) + protected function getMapper(bool $matchSingle = false): LastnameMapper { $english = new English(); diff --git a/tests/Mapper/MiddlenameMapperTest.php b/tests/Mapper/MiddlenameMapperTest.php index badd1d0..1a33fbc 100644 --- a/tests/Mapper/MiddlenameMapperTest.php +++ b/tests/Mapper/MiddlenameMapperTest.php @@ -10,9 +10,9 @@ class MiddlenameMapperTest extends AbstractMapperTestCase { /** - * @return array + * @return array> */ - public static function provider() + public static function provider(): array { return [ [ @@ -93,7 +93,7 @@ public static function provider() ]; } - protected function getMapper($mapWithoutLastname = false) + protected function getMapper(bool $mapWithoutLastname = false): MiddlenameMapper { return new MiddlenameMapper($mapWithoutLastname); } diff --git a/tests/Mapper/NicknameMapperTest.php b/tests/Mapper/NicknameMapperTest.php index eca5d2e..71bb786 100644 --- a/tests/Mapper/NicknameMapperTest.php +++ b/tests/Mapper/NicknameMapperTest.php @@ -9,9 +9,9 @@ class NicknameMapperTest extends AbstractMapperTestCase { /** - * @return array + * @return array> */ - public static function provider() + public static function provider(): array { return [ [ @@ -110,7 +110,7 @@ public static function provider() ]; } - protected function getMapper() + protected function getMapper(): NicknameMapper { return new NicknameMapper([ '[' => ']', diff --git a/tests/Mapper/SalutationMapperTest.php b/tests/Mapper/SalutationMapperTest.php index cc782f9..b6d0d3c 100644 --- a/tests/Mapper/SalutationMapperTest.php +++ b/tests/Mapper/SalutationMapperTest.php @@ -10,9 +10,9 @@ class SalutationMapperTest extends AbstractMapperTestCase { /** - * @return array + * @return array> */ - public static function provider() + public static function provider(): array { return [ [ @@ -52,7 +52,7 @@ public static function provider() ]; } - protected function getMapper() + protected function getMapper(): SalutationMapper { $english = new English(); diff --git a/tests/Mapper/SuffixMapperTest.php b/tests/Mapper/SuffixMapperTest.php index 3361185..6add4ce 100644 --- a/tests/Mapper/SuffixMapperTest.php +++ b/tests/Mapper/SuffixMapperTest.php @@ -11,9 +11,9 @@ class SuffixMapperTest extends AbstractMapperTestCase { /** - * @return array + * @return array> */ - public static function provider() + public static function provider(): array { return [ [ @@ -156,7 +156,7 @@ public static function provider() ]; } - protected function getMapper($matchSinglePart = false, $reservedParts = 2) + protected function getMapper(bool $matchSinglePart = false, int $reservedParts = 2): SuffixMapper { $english = new English(); diff --git a/tests/NameTest.php b/tests/NameTest.php index 7a87261..37190e2 100644 --- a/tests/NameTest.php +++ b/tests/NameTest.php @@ -16,7 +16,7 @@ class NameTest extends TestCase { - public function testToString() + public function testToString(): void { $parts = [ new Salutation('Mr', 'Mr.'), @@ -34,7 +34,7 @@ public function testToString() $this->assertSame('Mr. James (Jim) Morgan T. Smith I', (string) $name); } - public function testGetNickname() + public function testGetNickname(): void { $name = new Name([ new Nickname('Jim'), @@ -44,7 +44,7 @@ public function testGetNickname() $this->assertSame('(Jim)', $name->getNickname(true)); } - public function testGettingLastnameAndLastnamePrefixSeparately() + public function testGettingLastnameAndLastnamePrefixSeparately(): void { $name = new Name([ new Firstname('Frank'), diff --git a/tests/ParserTest.php b/tests/ParserTest.php index d4c8bf1..d148157 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -11,9 +11,9 @@ class ParserTest extends TestCase { /** - * @return array + * @return array}> */ - public static function provider() + public static function provider(): array { return [ [ @@ -565,8 +565,11 @@ public static function provider() ]; } + /** + * @param array $expectation + */ #[DataProvider('provider')] - public function testParse($input, $expectation) + public function testParse(string $input, array $expectation): void { $parser = new Parser(); $name = $parser->parse($input); @@ -575,7 +578,7 @@ public function testParse($input, $expectation) $this->assertEquals($expectation, $name->getAll()); } - public function testSetGetWhitespace() + public function testSetGetWhitespace(): void { $parser = new Parser(); $parser->setWhitespace('abc'); @@ -586,7 +589,7 @@ public function testSetGetWhitespace() $this->assertSame(' _', $parser->getWhitespace()); } - public function testSetGetNicknameDelimiters() + public function testSetGetNicknameDelimiters(): void { $parser = new Parser(); $parser->setNicknameDelimiters(['[' => ']']); @@ -595,7 +598,7 @@ public function testSetGetNicknameDelimiters() $this->assertNotSame('Jim', $parser->parse('(Jim)')->getNickname()); } - public function testSetMaxSalutationIndex() + public function testSetMaxSalutationIndex(): void { $parser = new Parser(); $this->assertSame(0, $parser->getMaxSalutationIndex()); @@ -610,7 +613,7 @@ public function testSetMaxSalutationIndex() $this->assertSame('Mr.', $parser->parse('Francis Mr')->getSalutation()); } - public function testSetMaxCombinedInitials() + public function testSetMaxCombinedInitials(): void { $parser = new Parser(); $this->assertSame(2, $parser->getMaxCombinedInitials()); @@ -625,7 +628,7 @@ public function testSetMaxCombinedInitials() $this->assertSame('P A G', $parser->parse('Charles PAG Mountbatten-Windsor')->getInitials()); } - public function testParserAndSubparsersProperlyHandleLanguages() + public function testParserAndSubparsersProperlyHandleLanguages(): void { $parser = new Parser([ new German(), diff --git a/tests/Part/AbstractPartTest.php b/tests/Part/AbstractPartTest.php index d3c5b7a..1982b6a 100644 --- a/tests/Part/AbstractPartTest.php +++ b/tests/Part/AbstractPartTest.php @@ -7,13 +7,13 @@ class AbstractPartTest extends TestCase { - public function testNormalize() + public function testNormalize(): void { $part = new class ('abc') extends AbstractPart {}; $this->assertEquals('abc', $part->normalize()); } - public function testSetValueUnwraps() + public function testSetValueUnwraps(): void { $part = new class ('abc') extends AbstractPart {}; $this->assertEquals('abc', $part->getValue()); diff --git a/tests/Part/NormalisationTest.php b/tests/Part/NormalisationTest.php index 311da18..6375620 100644 --- a/tests/Part/NormalisationTest.php +++ b/tests/Part/NormalisationTest.php @@ -19,7 +19,7 @@ public static function setUpBeforeClass(): void /** * make sure we test both with and without mb_string support */ - public function testCamelcasingWorksWithMbString() + public function testCamelcasingWorksWithMbString(): void { $functionExistsMock = $this->getFunctionMock(__NAMESPACE__, 'function_exists'); $functionExistsMock->expects($this->any()) @@ -48,7 +48,7 @@ public function testCamelcasingWorksWithMbString() /** * make sure we test both with and without mb_string support */ - public function testCamelcasingWorksWithoutMbString() + public function testCamelcasingWorksWithoutMbString(): void { $functionExistsMock = $this->getFunctionMock(__NAMESPACE__, 'function_exists'); $functionExistsMock->expects($this->any()) From c851170ea25280f2e987a11c1194fd9e7e9d4569 Mon Sep 17 00:00:00 2001 From: Zachary Miller Date: Sun, 10 May 2026 17:55:01 -0400 Subject: [PATCH 12/14] Simplify pass: PartArray alias, Parser memoization, doc cleanup Code reuse: - Add @phpstan-type PartArray = array alias on AbstractMapper; concrete mappers @phpstan-import-type the alias. Replaces 25+ verbose array with PartArray throughout. DRY and reads cleaner. Efficiency (real perf win): - Memoize Parser::getPrefixes/getSuffixes/getSalutations. Previously they re-iterated all $this->languages and merged their dictionaries on every call - 2-3 times per parse for split (comma-separated) names. Now cached in private nullable properties; assigned on first access via ??=. - Extracted the 3 duplicated language-merge loops into one private mergeFromLanguages(string \$method) helper. Code quality: - Remove "map [thing] in (the) parts array" docblock noise from the 6 remaining concrete mappers - it just restated what the well-named method already conveys. Kept the @param PartArray / @return PartArray annotations since the alias carries real info. - Add one-line WHY comment on the preg_replace ?? \$name fallback in Parser::normalize and AbstractPart::camelcase: preg_replace can return null on regex compile error (e.g., user-set invalid whitespace pattern). Verified post-simplify: - 131 tests, 235 assertions: pass - PHPStan level 9: 0 errors - PHP-CS-Fixer: 0 fixable --- src/Mapper/AbstractMapper.php | 11 ++++--- src/Mapper/FirstnameMapper.php | 13 ++++---- src/Mapper/InitialMapper.php | 9 +++--- src/Mapper/LastnameMapper.php | 29 +++++++++--------- src/Mapper/MiddlenameMapper.php | 13 ++++---- src/Mapper/NicknameMapper.php | 9 +++--- src/Mapper/SalutationMapper.php | 15 ++++----- src/Mapper/SuffixMapper.php | 11 ++++--- src/Parser.php | 54 ++++++++++++++++++++++----------- src/Part/AbstractPart.php | 1 + 10 files changed, 98 insertions(+), 67 deletions(-) diff --git a/src/Mapper/AbstractMapper.php b/src/Mapper/AbstractMapper.php index 418f84a..e277142 100644 --- a/src/Mapper/AbstractMapper.php +++ b/src/Mapper/AbstractMapper.php @@ -4,20 +4,23 @@ use CodeByZach\NameParser\Part\AbstractPart; +/** + * @phpstan-type PartArray array + */ abstract class AbstractMapper { /** * implements the mapping of parts * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ abstract public function map(array $parts): array; /** * checks if there are still unmapped parts left before the given position * - * @param array $parts + * @param PartArray $parts */ protected function hasUnmappedPartsBefore(array $parts, int $index): bool { @@ -36,7 +39,7 @@ protected function hasUnmappedPartsBefore(array $parts, int $index): bool /** * @param class-string $type - * @param array $parts + * @param PartArray $parts */ protected function findFirstMapped(string $type, array $parts): int|false { diff --git a/src/Mapper/FirstnameMapper.php b/src/Mapper/FirstnameMapper.php index 0f6f234..6722c7e 100644 --- a/src/Mapper/FirstnameMapper.php +++ b/src/Mapper/FirstnameMapper.php @@ -8,13 +8,14 @@ use CodeByZach\NameParser\Part\Lastname; use CodeByZach\NameParser\Part\Salutation; +/** + * @phpstan-import-type PartArray from AbstractMapper + */ class FirstnameMapper extends AbstractMapper { /** - * map firstnames in parts array - * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ #[\Override] public function map(array $parts): array @@ -42,7 +43,7 @@ protected function handleSinglePart(string|AbstractPart $part): AbstractPart } /** - * @param array $parts + * @param PartArray $parts */ protected function findFirstnamePosition(array $parts): ?int { @@ -73,7 +74,7 @@ protected function findFirstnamePosition(array $parts): ?int } /** - * @param array $parts + * @param PartArray $parts */ protected function getStartIndex(array $parts): int { diff --git a/src/Mapper/InitialMapper.php b/src/Mapper/InitialMapper.php index 5268dba..78fc900 100644 --- a/src/Mapper/InitialMapper.php +++ b/src/Mapper/InitialMapper.php @@ -8,6 +8,9 @@ /** * single letter, possibly followed by a period */ +/** + * @phpstan-import-type PartArray from AbstractMapper + */ class InitialMapper extends AbstractMapper { public function __construct( @@ -16,10 +19,8 @@ public function __construct( ) {} /** - * map intials in parts array - * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ #[\Override] public function map(array $parts): array diff --git a/src/Mapper/LastnameMapper.php b/src/Mapper/LastnameMapper.php index 3d8d4d1..4ba47bf 100644 --- a/src/Mapper/LastnameMapper.php +++ b/src/Mapper/LastnameMapper.php @@ -9,6 +9,9 @@ use CodeByZach\NameParser\Part\Salutation; use CodeByZach\NameParser\Part\Suffix; +/** + * @phpstan-import-type PartArray from AbstractMapper + */ class LastnameMapper extends AbstractMapper { /** @@ -20,10 +23,8 @@ public function __construct( ) {} /** - * map lastnames in the parts array - * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ #[\Override] public function map(array $parts): array @@ -39,8 +40,8 @@ public function map(array $parts): array * we map the parts in reverse order because it makes more * sense to parse for the lastname starting from the end * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ protected function mapParts(array $parts): array { @@ -81,7 +82,7 @@ protected function mapParts(array $parts): array * try to map this part as a lastname prefix or as a combined * lastname part containing a prefix * - * @param array $parts + * @param PartArray $parts */ private function mapAsPrefixIfPossible(array $parts, int $k): ?Lastname { @@ -120,7 +121,7 @@ private function isCombinedWithPrefix(string $part): bool /** * skip through the parts we want to ignore and return the start index * - * @param array $parts + * @param PartArray $parts */ protected function skipIgnoredParts(array $parts): int { @@ -141,7 +142,7 @@ protected function skipIgnoredParts(array $parts): int * the assumption is that lastname parts have already been found * but we want to see if we should add more parts * - * @param array $parts + * @param PartArray $parts */ protected function shouldStopMapping(array $parts, int $k): bool { @@ -172,8 +173,8 @@ protected function isIgnoredPart(AbstractPart|string $part): bool * if the mapping did not derive any lastname this is called to transform * any previously ignored parts into lastname parts * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ protected function remapIgnored(array $parts): array { @@ -193,7 +194,7 @@ protected function remapIgnored(array $parts): array } /** - * @param array $parts + * @param PartArray $parts */ protected function isFollowedByLastnamePart(array $parts, int $index): bool { @@ -212,7 +213,7 @@ protected function isFollowedByLastnamePart(array $parts, int $index): bool * * This expects the parts array and index to be in the original order. * - * @param array $parts + * @param PartArray $parts */ protected function isApplicablePrefix(array $parts, int $index): bool { @@ -236,7 +237,7 @@ protected function isPrefix(string $word): bool /** * find the next non-nickname index in parts * - * @param array $parts + * @param PartArray $parts */ protected function skipNicknameParts(array $parts, int $startIndex): int { diff --git a/src/Mapper/MiddlenameMapper.php b/src/Mapper/MiddlenameMapper.php index 4bdd309..9a73ede 100644 --- a/src/Mapper/MiddlenameMapper.php +++ b/src/Mapper/MiddlenameMapper.php @@ -7,6 +7,9 @@ use CodeByZach\NameParser\Part\Lastname; use CodeByZach\NameParser\Part\Middlename; +/** + * @phpstan-import-type PartArray from AbstractMapper + */ class MiddlenameMapper extends AbstractMapper { public function __construct( @@ -14,10 +17,8 @@ public function __construct( ) {} /** - * map middlenames in the parts array - * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ #[\Override] public function map(array $parts): array @@ -39,8 +40,8 @@ public function map(array $parts): array } /** - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ protected function mapFrom(int $start, array $parts): array { diff --git a/src/Mapper/NicknameMapper.php b/src/Mapper/NicknameMapper.php index b5e2bc8..eb023af 100644 --- a/src/Mapper/NicknameMapper.php +++ b/src/Mapper/NicknameMapper.php @@ -5,6 +5,9 @@ use CodeByZach\NameParser\Part\AbstractPart; use CodeByZach\NameParser\Part\Nickname; +/** + * @phpstan-import-type PartArray from AbstractMapper + */ class NicknameMapper extends AbstractMapper { /** @@ -30,10 +33,8 @@ public function __construct(array $delimiters = []) } /** - * map nicknames in the parts array - * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ #[\Override] public function map(array $parts): array diff --git a/src/Mapper/SalutationMapper.php b/src/Mapper/SalutationMapper.php index 8751212..255e8c7 100644 --- a/src/Mapper/SalutationMapper.php +++ b/src/Mapper/SalutationMapper.php @@ -5,6 +5,9 @@ use CodeByZach\NameParser\Part\AbstractPart; use CodeByZach\NameParser\Part\Salutation; +/** + * @phpstan-import-type PartArray from AbstractMapper + */ class SalutationMapper extends AbstractMapper { /** @@ -16,10 +19,8 @@ public function __construct( ) {} /** - * map salutations in the parts array - * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ #[\Override] public function map(array $parts): array @@ -42,8 +43,8 @@ public function map(array $parts): array * not only single-word matches but also combined matches with * subsequent words (parts). * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ protected function substituteWithSalutation(array $parts, int $start): array { @@ -77,7 +78,7 @@ protected function substituteWithSalutation(array $parts, int $start): array * the subset words * * @param array $keys - * @param array $subset + * @param PartArray $subset * * @phpstan-assert-if-true array $subset */ diff --git a/src/Mapper/SuffixMapper.php b/src/Mapper/SuffixMapper.php index f3d6c4d..7d4371a 100644 --- a/src/Mapper/SuffixMapper.php +++ b/src/Mapper/SuffixMapper.php @@ -5,6 +5,9 @@ use CodeByZach\NameParser\Part\AbstractPart; use CodeByZach\NameParser\Part\Suffix; +/** + * @phpstan-import-type PartArray from AbstractMapper + */ class SuffixMapper extends AbstractMapper { /** @@ -17,10 +20,8 @@ public function __construct( ) {} /** - * map suffixes in the parts array - * - * @param array $parts - * @return array + * @param PartArray $parts + * @return PartArray */ #[\Override] public function map(array $parts): array @@ -51,7 +52,7 @@ public function map(array $parts): array } /** - * @param array $parts + * @param PartArray $parts */ protected function isMatchingSinglePart(array $parts): bool { diff --git a/src/Parser.php b/src/Parser.php index 2064167..736dfc0 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -34,6 +34,27 @@ class Parser protected int $maxCombinedInitials = 2; + /** + * memoized merge of all languages' lastname prefixes + * + * @var array|null + */ + private ?array $prefixes = null; + + /** + * memoized merge of all languages' suffixes + * + * @var array|null + */ + private ?array $suffixes = null; + + /** + * memoized merge of all languages' salutations + * + * @var array|null + */ + private ?array $salutations = null; + /** * @param array $languages */ @@ -172,6 +193,8 @@ protected function normalize(string $name): string $name = trim($name); + // preg_replace returns null on regex compile error; user-set whitespace + // characters might produce an invalid pattern, so fall back to the input. return preg_replace('/[' . preg_quote($whitespace, '/') . ']+/', ' ', $name) ?? $name; } @@ -198,13 +221,7 @@ public function setWhitespace(string $whitespace): Parser */ protected function getPrefixes(): array { - $prefixes = []; - - foreach ($this->languages as $language) { - $prefixes += $language->getLastnamePrefixes(); - } - - return $prefixes; + return $this->prefixes ??= $this->mergeFromLanguages('getLastnamePrefixes'); } /** @@ -212,13 +229,7 @@ protected function getPrefixes(): array */ protected function getSuffixes(): array { - $suffixes = []; - - foreach ($this->languages as $language) { - $suffixes += $language->getSuffixes(); - } - - return $suffixes; + return $this->suffixes ??= $this->mergeFromLanguages('getSuffixes'); } /** @@ -226,13 +237,22 @@ protected function getSuffixes(): array */ protected function getSalutations(): array { - $salutations = []; + return $this->salutations ??= $this->mergeFromLanguages('getSalutations'); + } + + /** + * @param 'getSuffixes'|'getSalutations'|'getLastnamePrefixes' $method + * @return array + */ + private function mergeFromLanguages(string $method): array + { + $merged = []; foreach ($this->languages as $language) { - $salutations += $language->getSalutations(); + $merged += $language->$method(); } - return $salutations; + return $merged; } /** diff --git a/src/Part/AbstractPart.php b/src/Part/AbstractPart.php index 28b9455..60cd14e 100644 --- a/src/Part/AbstractPart.php +++ b/src/Part/AbstractPart.php @@ -58,6 +58,7 @@ protected function camelcase(string $word): string return $word; } + // preg_replace_callback returns null on regex error; fall back to the input. return preg_replace_callback('/[\p{L}0-9]+/ui', $this->camelcaseReplace(...), $word) ?? $word; } From db2712bc461a01c607ec27cd7d15e751af998c2a Mon Sep 17 00:00:00 2001 From: Zachary Miller Date: Sun, 10 May 2026 18:00:16 -0400 Subject: [PATCH 13/14] name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c1dc48..9b7aed6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# CodeByZach Name Parser +# Name Parser