diff --git a/composer.json b/composer.json index 174aa69..10bf046 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,9 @@ "require-dev": { "phpunit/phpunit": "^11.2", - "rector/rector": "^1.2" + "rector/rector": "^1.2", + "ifcastle/codestyle": "^0.1.7", + "phpstan/phpstan": "^1.12" }, "scripts": { "test": "vendor/bin/phpunit ./tests" diff --git a/composer.lock b/composer.lock index 8229388..7d36996 100644 --- a/composer.lock +++ b/composer.lock @@ -4,396 +4,2602 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "93a720890e0fe41a8c7482a46974d316", + "content-hash": "f353695b002cdd50b794ab82102789ff", "packages": [], "packages-dev": [ { - "name": "myclabs/deep-copy", - "version": "1.12.0", + "name": "clue/ndjson-react", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3 <3.2.2" + "php": ">=5.3", + "react/stream": "^1.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" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" }, "type": "library", "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], "psr-4": { - "DeepCopy\\": "src/DeepCopy/" + "Clue\\React\\NDJson\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" ], "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" }, "funding": [ { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" } ], - "time": "2024-06-12T14:39:25+00:00" + "time": "2022-12-23T10:58:28+00:00" }, { - "name": "nikic/php-parser", - "version": "v5.1.0", + "name": "composer/pcre", + "version": "3.3.1", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" + "url": "https://github.com/composer/pcre.git", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", - "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" }, "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^9.0" + "phpstan/phpstan": "^1.11.10", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8 || ^9" }, - "bin": [ - "bin/php-parse" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "3.x-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] } }, "autoload": { "psr-4": { - "PhpParser\\": "lib/PhpParser" + "Composer\\Pcre\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" } ], - "description": "A PHP parser written in PHP", + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", "keywords": [ - "parser", - "php" + "PCRE", + "preg", + "regex", + "regular expression" ], "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0" + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.1" }, - "time": "2024-07-01T20:03:41+00:00" + "funding": [ + { + "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-08-27T18:44:43+00:00" }, { - "name": "phar-io/manifest", - "version": "2.0.4", + "name": "composer/semver", + "version": "3.4.3", "source": { "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "54750ef60c58e43759730615a392c31c80e23176" + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", - "reference": "54750ef60c58e43759730615a392c31c80e23176", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Composer\\Semver\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" }, { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], "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/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" }, "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-09-19T14:15:21+00:00" }, { - "name": "phar-io/version", - "version": "3.2.1", + "name": "composer/xdebug-handler", + "version": "3.0.5", "source": { "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "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": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "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://packagist.com", + "type": "custom" }, { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "url": "https://github.com/composer", + "type": "github" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" } ], - "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" + "time": "2024-05-06T16:37:16+00:00" }, { - "name": "phpstan/phpstan", - "version": "1.12.0", + "name": "evenement/evenement", + "version": "v3.0.2", "source": { "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "384af967d35b2162f69526c7276acadce534d0e1" + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/384af967d35b2162f69526c7276acadce534d0e1", - "reference": "384af967d35b2162f69526c7276acadce534d0e1", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": ">=7.0" }, - "conflict": { - "phpstan/phpstan-shim": "*" + "require-dev": { + "phpunit/phpunit": "^9 || ^6" }, - "bin": [ - "phpstan", - "phpstan.phar" - ], "type": "library", "autoload": { - "files": [ - "bootstrap.php" - ] + "psr-4": { + "Evenement\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "PHPStan - PHP Static Analysis Tool", + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", "keywords": [ - "dev", - "static analysis" + "event-dispatcher", + "event-emitter" ], "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/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" }, - "funding": [ - { - "url": "https://github.com/ondrejmirtes", - "type": "github" - }, - { - "url": "https://github.com/phpstan", - "type": "github" - } - ], - "time": "2024-08-27T09:18:05+00:00" + "time": "2023-08-08T05:53:35+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "11.0.6", + "name": "fidry/cpu-core-counter", + "version": "1.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ebdffc9e09585dafa71b9bffcdb0a229d4704c45" + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ebdffc9e09585dafa71b9bffcdb0a229d4704c45", - "reference": "ebdffc9e09585dafa71b9bffcdb0a229d4704c45", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^5.1.0", - "php": ">=8.2", - "phpunit/php-file-iterator": "^5.0.1", - "phpunit/php-text-template": "^4.0.1", - "sebastian/code-unit-reverse-lookup": "^4.0.1", - "sebastian/complexity": "^4.0.1", - "sebastian/environment": "^7.2.0", - "sebastian/lines-of-code": "^3.0.1", - "sebastian/version": "^5.0.1", - "theseer/tokenizer": "^1.2.3" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "11.0.x-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "description": "Tiny utility to get the number of CPU cores.", "keywords": [ - "coverage", - "testing", - "xunit" + "CPU", + "core" ], "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.6" + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/theofidry", "type": "github" } ], - "time": "2024-08-22T04:37:56+00:00" + "time": "2024-08-06T10:04:20+00:00" }, { - "name": "phpunit/php-file-iterator", - "version": "5.1.0", + "name": "friendsofphp/php-cs-fixer", + "version": "v3.64.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "58dd9c931c785a79739310aef5178928305ffa67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/58dd9c931c785a79739310aef5178928305ffa67", + "reference": "58dd9c931c785a79739310aef5178928305ffa67", + "shasum": "" + }, + "require": { + "clue/ndjson-react": "^1.0", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.0", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.5", + "react/event-loop": "^1.0", + "react/promise": "^2.0 || ^3.0", + "react/socket": "^1.0", + "react/stream": "^1.0", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3 || ^2.3", + "infection/infection": "^0.29.5", + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.7", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", + "phpunit/phpunit": "^9.6.19 || ^10.5.21 || ^11.2", + "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "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/Fixer/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.64.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2024-08-30T23:09:38+00:00" + }, + { + "name": "ifcastle/codestyle", + "version": "v0.1.7", + "source": { + "type": "git", + "url": "https://github.com/EdmondDantes/ifcastle-codestyle.git", + "reference": "b009a6a00a548ed5906094ca12e7068461451dec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/EdmondDantes/ifcastle-codestyle/zipball/b009a6a00a548ed5906094ca12e7068461451dec", + "reference": "b009a6a00a548ed5906094ca12e7068461451dec", + "shasum": "" + }, + "require": { + "friendsofphp/php-cs-fixer": "^3.64", + "php": ">=8.3", + "phpstan/phpstan": "^1.12", + "rector/rector": "^1.2" + }, + "type": "codestyle", + "autoload": { + "psr-4": { + "IfCastle\\CodeStyle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "CodeStyle", + "keywords": [ + "Codestyle", + "ifcastle" + ], + "support": { + "issues": "https://github.com/EdmondDantes/ifcastle-codestyle/issues", + "source": "https://github.com/EdmondDantes/ifcastle-codestyle/tree/v0.1.7" + }, + "time": "2024-10-26T13:56:03+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.12.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "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.12.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2024-06-12T14:39:25+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "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.0-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.1.0" + }, + "time": "2024-07-01T20:03:41+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": "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": "phpstan/phpstan", + "version": "1.12.7", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "dc2b9976bd8b0f84ec9b0e50cc35378551de7af0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc2b9976bd8b0f84ec9b0e50cc35378551de7af0", + "reference": "dc2b9976bd8b0f84ec9b0e50cc35378551de7af0", + "shasum": "" + }, + "require": { + "php": "^7.2|^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": "2024-10-18T11:12:07+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "ebdffc9e09585dafa71b9bffcdb0a229d4704c45" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ebdffc9e09585dafa71b9bffcdb0a229d4704c45", + "reference": "ebdffc9e09585dafa71b9bffcdb0a229d4704c45", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.1.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.1", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "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": "11.0.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/11.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:37:56+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.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": "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/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-27T05:02:59+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "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": "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/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.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/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.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", + "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/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.3.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "fe179875ef0c14e90b75617002767eae0a742641" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fe179875ef0c14e90b75617002767eae0a742641", + "reference": "fe179875ef0c14e90b75617002767eae0a742641", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.12.0", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.5", + "phpunit/php-file-iterator": "^5.0.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.1", + "sebastian/comparator": "^6.0.2", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.1.3", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.0.1", + "sebastian/version": "^5.0.1" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.3-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/11.3.1" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-08-13T06:14:23+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.5", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", + "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", + "react/socket": "^1.8", + "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.5" + }, + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-09-16T13:41:56+00:00" + }, + { + "name": "react/dns", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "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.13.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-13T14:18:03+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "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.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/promise", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.10.39 || 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.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-05-24T10:39:05+00:00" + }, + { + "name": "react/socket", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "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.16.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-07-26T10:38:09+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": "rector/rector", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "42a4aa23b48b4cfc8ebfeac2b570364e27744381" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/42a4aa23b48b4cfc8ebfeac2b570364e27744381", + "reference": "42a4aa23b48b4cfc8ebfeac2b570364e27744381", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.11.11" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "suggest": { + "ext-dom": "To manipulate phpunit.xml via the custom-rule command" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/1.2.4" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2024-08-23T09:03:01+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.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 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": "sebastian/code-unit", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.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": "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:44:28+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "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": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "450d8f237bd611c45b5acf0733ce43e6bb280f81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/450d8f237bd611c45b5acf0733ce43e6bb280f81", + "reference": "450d8f237bd611c45b5acf0733ce43e6bb280f81", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.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" + }, + { + "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/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-12T06:07:25+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.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/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "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" + }, + { + "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/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.2-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/7.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:54:44+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.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": "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/6.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:56:19+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.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" + } + ], + "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/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "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" }, "require-dev": { @@ -402,7 +2608,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -421,16 +2627,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": "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/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.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/3.0.1" }, "funding": [ { @@ -438,36 +2640,34 @@ "type": "github" } ], - "time": "2024-08-27T05:02:59+00:00" + "time": "2024-07-03T04:58:38+00:00" }, { - "name": "phpunit/php-invoker", - "version": "5.0.1", + "name": "sebastian/object-enumerator", + "version": "6.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "ext-pcntl": "*", "phpunit/phpunit": "^11.0" }, - "suggest": { - "ext-pcntl": "*" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -482,19 +2682,15 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], + "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/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/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, "funding": [ { @@ -502,20 +2698,20 @@ "type": "github" } ], - "time": "2024-07-03T05:07:44+00:00" + "time": "2024-07-03T05:00:13+00:00" }, { - "name": "phpunit/php-text-template", + "name": "sebastian/object-reflector", "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { @@ -542,19 +2738,15 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], + "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/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/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": [ { @@ -562,20 +2754,20 @@ "type": "github" } ], - "time": "2024-07-03T05:08:43+00:00" + "time": "2024-07-03T05:01:32+00:00" }, { - "name": "phpunit/php-timer", - "version": "7.0.1", + "name": "sebastian/recursion-context", + "version": "6.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", "shasum": "" }, "require": { @@ -587,7 +2779,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -602,19 +2794,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": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "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" + "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.2" }, "funding": [ { @@ -622,65 +2818,89 @@ "type": "github" } ], - "time": "2024-07-03T05:09:35+00:00" + "time": "2024-07-03T05:10:34+00:00" }, { - "name": "phpunit/phpunit", - "version": "11.3.1", + "name": "sebastian/type", + "version": "5.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "fe179875ef0c14e90b75617002767eae0a742641" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fe179875ef0c14e90b75617002767eae0a742641", - "reference": "fe179875ef0c14e90b75617002767eae0a742641", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb6a6566f9589e86661291d13eba708cce5eb4aa", + "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.0", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", - "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.5", - "phpunit/php-file-iterator": "^5.0.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.1", - "sebastian/comparator": "^6.0.2", - "sebastian/diff": "^6.0.2", - "sebastian/environment": "^7.2.0", - "sebastian/exporter": "^6.1.3", - "sebastian/global-state": "^7.0.2", - "sebastian/object-enumerator": "^6.0.1", - "sebastian/type": "^5.0.1", - "sebastian/version": "^5.0.1" + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.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": "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.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:11:49+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/45c9debb7d039ce9b97de2f749c2cf5832a06ac4", + "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4", + "shasum": "" }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" + "require": { + "php": ">=8.2" }, - "bin": [ - "phpunit" - ], "type": "library", "extra": { "branch-alias": { - "dev-main": "11.3-dev" + "dev-main": "5.0-dev" } }, "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], "classmap": [ "src/" ] @@ -696,1015 +2916,1300 @@ "role": "lead" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], + "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/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.3.1" + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.1" }, "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" } ], - "time": "2024-08-13T06:14:23+00:00" + "time": "2024-07-03T05:13:08+00:00" }, { - "name": "rector/rector", - "version": "1.2.4", + "name": "symfony/console", + "version": "v7.1.5", "source": { "type": "git", - "url": "https://github.com/rectorphp/rector.git", - "reference": "42a4aa23b48b4cfc8ebfeac2b570364e27744381" + "url": "https://github.com/symfony/console.git", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/42a4aa23b48b4cfc8ebfeac2b570364e27744381", - "reference": "42a4aa23b48b4cfc8ebfeac2b570364e27744381", + "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", "shasum": "" }, "require": { - "php": "^7.2|^8.0", - "phpstan/phpstan": "^1.11.11" + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" }, "conflict": { - "rector/rector-doctrine": "*", - "rector/rector-downgrade-php": "*", - "rector/rector-phpunit": "*", - "rector/rector-symfony": "*" + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, - "suggest": { - "ext-dom": "To manipulate phpunit.xml via the custom-rule command" + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, - "bin": [ - "bin/rector" - ], "type": "library", "autoload": { - "files": [ - "bootstrap.php" + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", "keywords": [ - "automation", - "dev", - "migration", - "refactoring" + "cli", + "command-line", + "console", + "terminal" ], "support": { - "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/1.2.4" + "source": "https://github.com/symfony/console/tree/v7.1.5" }, "funding": [ { - "url": "https://github.com/tomasvotruba", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-08-23T09:03:01+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { - "name": "sebastian/cli-parser", - "version": "3.0.2", + "name": "symfony/deprecation-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "classmap": [ - "src/" + "files": [ + "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": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", + "description": "A generic function and convention to trigger deprecation notices", + "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/deprecation-contracts/tree/v3.5.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:41:36+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { - "name": "sebastian/code-unit", - "version": "3.0.1", + "name": "symfony/event-dispatcher", + "version": "v7.1.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "6bb7d09d6623567178cf54126afa9c2310114268" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268", - "reference": "6bb7d09d6623567178cf54126afa9c2310114268", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", + "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", "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", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.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": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", + "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/code-unit/issues", - "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.1" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:44:28+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "4.0.1", + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" }, "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/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "php": ">=8.1", + "psr/event-dispatcher": "^1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "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" + "name": "Nicolas Grekas", + "email": "p@tchwork.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": "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-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/event-dispatcher-contracts/tree/v3.5.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:45:54+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { - "name": "sebastian/comparator", - "version": "6.0.2", + "name": "symfony/filesystem", + "version": "v7.1.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "450d8f237bd611c45b5acf0733ce43e6bb280f81" + "url": "https://github.com/symfony/filesystem.git", + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/450d8f237bd611c45b5acf0733ce43e6bb280f81", - "reference": "450d8f237bd611c45b5acf0733ce43e6bb280f81", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a", + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-mbstring": "*", "php": ">=8.2", - "sebastian/diff": "^6.0", - "sebastian/exporter": "^6.0" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "symfony/process": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.1.5" }, - "autoload": { - "classmap": [ - "src/" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-17T09:16:35+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.1.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "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.0.2" + "source": "https://github.com/symfony/finder/tree/v7.1.4" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-08-12T06:07:25+00:00" + "time": "2024-08-13T14:28:19+00:00" }, { - "name": "sebastian/complexity", - "version": "4.0.1", + "name": "symfony/options-resolver", + "version": "v7.1.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55" }, "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/47aa818121ed3950acd2b58d1d37d08a94f9bf55", + "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55", "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.1.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:49:50+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { - "name": "sebastian/diff", - "version": "6.0.2", + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "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/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "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": { + "name": "symfony/polyfill", + "url": "https://github.com/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.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:53:05+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/environment", - "version": "7.2.0", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "php": ">=7.2" }, "suggest": { - "ext-posix": "*" + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "7.2-dev" + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/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.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:54:44+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/exporter", - "version": "6.1.3", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", - "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "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.2" + "suggest": { + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "6.1-dev" + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/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.1.3" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:56:19+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/global-state", - "version": "7.0.2", + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "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/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" + "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": { + "name": "symfony/polyfill", + "url": "https://github.com/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" + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:57:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/lines-of-code", - "version": "3.0.1", + "name": "symfony/polyfill-php80", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.0-dev" + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/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.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:58:38+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "6.0.1", + "name": "symfony/polyfill-php81", + "version": "v1.31.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": { + "name": "symfony/polyfill", + "url": "https://github.com/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.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "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/process", + "version": "v7.1.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + "url": "https://github.com/symfony/process.git", + "reference": "5c03ee6369281177f07f7c68252a280beccba847" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", + "reference": "5c03ee6369281177f07f7c68252a280beccba847", "shasum": "" }, "require": { "php": ">=8.2" }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.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": "Fabien Potencier", + "email": "fabien@symfony.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": "Executes commands in sub-processes", + "homepage": "https://symfony.com", "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/process/tree/v7.1.5" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T05:01:32+00:00" + "time": "2024-09-19T21:48:23+00:00" }, { - "name": "sebastian/recursion-context", - "version": "6.0.2", + "name": "symfony/service-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "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.0" + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "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" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.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": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "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.2" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T05:10:34+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { - "name": "sebastian/type", - "version": "5.0.1", + "name": "symfony/stopwatch", + "version": "v7.1.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa" + "url": "https://github.com/symfony/stopwatch.git", + "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb6a6566f9589e86661291d13eba708cce5eb4aa", - "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", + "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "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": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.0.1" + "source": "https://github.com/symfony/stopwatch/tree/v7.1.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T05:11:49+00:00" + "time": "2024-05-31T14:57:53+00:00" }, { - "name": "sebastian/version", - "version": "5.0.1", + "name": "symfony/string", + "version": "v7.1.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4" + "url": "https://github.com/symfony/string.git", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/45c9debb7d039ce9b97de2f749c2cf5832a06ac4", - "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4", + "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" }, + "type": "library", "autoload": { - "classmap": [ - "src/" + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "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": "Nicolas Grekas", + "email": "p@tchwork.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 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": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], "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.1" + "source": "https://github.com/symfony/string/tree/v7.1.5" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T05:13:08+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "theseer/tokenizer", diff --git a/docs/00-Introduction.md b/docs/00-Introduction.md index c543a52..e82f6a0 100644 --- a/docs/00-Introduction.md +++ b/docs/00-Introduction.md @@ -1,32 +1,63 @@ # Introduction -**BaseException** - библиотека унификации исключений в *PHP*. +**BaseException** - библиотека унификации исключений для *PHP*. **BaseException** решает задачи: -1. Структурирование информации об исключении. +1. Метаданные исключений. +2. Шаблонизация сообщений. 2. Аспектирование исключений. 3. Нормализация исключений при помощи "контейнеров". 4. Регистрация исключений в глобальном реестре. -## Структурирование информации +## Метаданные исключений и шаблонизация -Базовый класс `\Exception` не позволяет хранить в исключении структуры данных, и после использовать их для анализа. **BaseException** даёт возможность передавать в исключение хэш-массив, тем самым создавая произвольные структуры. Эти данные являются контекстом исключения. +При анализе исключений важно иметь ясное представление о том, что произошло. +Для этого необходимо хранить метаданные исключения, которые помогут в дальнейшем анализе. +Данная библиотека реализует возможность создавать исключения с контекстом, который содержит метаданные исключения. + +Метаданные исключения представляют собой ассоциативный массив, +элементами которого могут быть только простые типы данных. ## Поддержка шаблонов сообщений -**BaseException** поддерживает концепцию *шаблона сообщения* (начиная с версии 2.0). Шаблон сообщения - это строка, содержащая *placeholders*, которые заменяются на значения данных из контекста исключения. Формат шаблона соответствует [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). +**BaseException** поддерживает концепцию *шаблона сообщения* (начиная с версии 2.0). +Шаблон сообщения - это строка, содержащая *placeholders*, +которые заменяются на значения данных из контекста исключения. +Формат шаблона соответствует [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). + +Когда исключение создаётся, в конструктор передаются данные, +которые будут использоваться для замены *placeholders* в шаблоне сообщения. +Конструктор использует шаблон и генерирует описание исключения по шаблону и метаданным. + +Шаблон исключения позволяет добиться нескольких важных бенефитов: +* Возможность перевода сообщений об ошибках на разные языки, основываясь на шаблоне. +* Возможность группировать исключения по шаблону. + +Шаблонизация сообщений позволяет записать в журнал не только результирующее сообщение, +но и данные, которые были использованы для его формирования: + +```php + $exception = new BaseException(['template' => 'User {user} from {ip} is not allowed', 'user' => $user, 'ip' => $ip]); + $logger->error($exception->getMessage(), $exception->getExceptionData()); +``` + +Это даёт возможность в дальнейшем анализировать журнал и понимать, +какие данные были использованы для формирования сообщения об ошибке, +группировать исключения по шаблону, либо делать поиск по метаданным. ## Аспектирование исключений -Аспект - это класс характеристик исключения, который позволяет обобщать код и задачи по обработке исключений. Например, аспекты позволяют ответить на вопросы: +Аспект - это класс характеристик исключения, который позволяет обобщать код и задачи по обработке исключений. +Например, аспекты позволяют ответить на вопросы: - кто виноват: программист или система; - что делать: игнорировать проблему или немедленно решать. ## Нормализация исключений -Нормализация исключений - это поддержка системой ограниченного числа выброшенных исключений. Она может достигаться методами: +Нормализация исключений - это поддержка системой ограниченного числа выброшенных исключений. +Она может достигаться такими способами: 1. Наследование. 2. Привидение к контейнеру. @@ -48,9 +79,9 @@ ## Регистрация исключений -Одной из самых важных причин создания **BaseException** была регистрация исключения в конструкторе. Такой подход гарантирует, что если программист решил сохранить исключение в журнале, то оно "скорее всего" туда попадёт. Это значит, что если исключение перехвачено и подавлено, оно всё равно попадёт в журнал. - -Таким образом **BaseException** заставляет задуматься над журналированием исключений в момент написания класса исключения. Для этого библиотека предоставляет простые способы управления журналированием исключений в виде методов `BaseException::is_loggable()` и `BaseException::set_loggable()`, а так же готовых классов. +**BaseException** позволяет регистрировать исключения в глобальном реестре до того, как исключение, будет выброшено. +На текущий момент эта возможность существует, но не используется на практике. +Тем не менее в некоторых ситуациях, она может стать дополнительным инструментом для анализа исключений. ## Небольшая библиотека готовых исключений diff --git a/docs/01-Overview.md b/docs/01-Overview.md index dc801b9..b30bed3 100644 --- a/docs/01-Overview.md +++ b/docs/01-Overview.md @@ -133,4 +133,4 @@ class MyException extends BaseException ## Registry -## StorageI +## StorageInterface diff --git a/docs/02-Paradigm.md b/docs/02-Paradigm.md index e7c1e22..1b5e009 100644 --- a/docs/02-Paradigm.md +++ b/docs/02-Paradigm.md @@ -1,314 +1,47 @@ # Paradigm -Исключения с точки зрения анализа Программного Обеспечения (ПО), представляют собою особый интерес, так как описывают отклонения от "идеального множества состояний". В теории, имея такую информацию программисты должны были бы быстро находить причины сбоев. Но теория, слишком часто остаётся наедине сама с собой. +## Исключения и логирование -Нередко бывают ситуации, когда поток исключений не только становится многочисленным, но и совершенно не воспроизводимым (повторное воспроизведение). А, иногда некоторые ошибки возникают спонтанно, без какой либо корреляции, словно эмоции у психопата[^1]. В конце концов дело доходит до полного игнорирования "непонятных" проблем. Хотя это не значит, что проблемы не "влияют" на умы разработчиков. +Создание классов исключений тесно связаны с методикой логирования. -Известное "Кто владеет информацией…" следовало бы уточнить: "Кто понимает…", или если уже совсем близко к теме: "Кто анализирует данные…" :). Но создание анализируемых журналов натыкается на "непреодолимые" препятствия: +Исключения создаются с двумя целями: -1. Структура журнала и связанный код часто меняются. (Особенно после завершения проекта) -2. На реализацию кода журналирования никогда не хватает времени. А для кода анализа - и подавно! -3. Код журналирования уродует "целевой" код. -4. Код, обслуживающий формирование журнала считается "нудным" :)[^2] +1. Передать информацию о произошедшей ошибке для кода. +2. Предоставить достаточную информацию для логирования. -Вспоминается: +Для решения первой задачи, используются классы и интерфейсы, позволяя коду по типу исключения определить, что произошло. +Для решения второй задачи, используются метаданные исключения, которые позволяют логировать исключения с дополнительной информацией. -```php - try - { - ... - } - catch(\Exception $e) - { - err_log($e); - // ^^^^^^^^^ - этого кода не должно здесь быть! - // а значит и try/catch тоже :) - - throw $e; - } -``` - -На самом деле основных причин две: - -1. Смешение целевого кода и кода журналирования. -2. Структурирование информации для журнала. - -А решение вопросов частого изменения структуры журнала и кода журналирования вполне можно решить при помощи обобщённого программирования. - -## Полковнику никто не пишет - -В фильме "Как украсть миллион" есть хорошая демонстрация эффекта "ЗАЯ"[3]: грабители несколько раз умышленно приводят в действие систему сигнализации. Охранники ничего не обнаруживают. И после очередной попытки систему отключают. - -А ведь вроде как обеспечили хорошие журналы, множество методов оповещения: - -- сбор логов по серверам, -- письма, -- sms. - -Почему же всё это "добро" не приносит пользы? Потому что работает замечательный "человеческий фактор": - -1. Человек способен эффективно различать только два вида сигналов. -2. Если один тип сигнала означает "опасность", но используется относительно часто или имеет закономерность, он утрачивает значение. -3. Если сигнал "опасность" должен быть вычленен между множества других сигналов, он утрачивает эффективность обнаружения. - -Иначе: - -1. Если у ошибок есть несколько уровней, то для человека имеют значения только два: "конец света" и "как нибудь проживём". -2. Если ошибки типа "конец света" возникают достаточно часто, они воспринимаются так же как и ошибки других уровней. -3. Если человек пытается найти ошибку "деление на ноль" среди массива ошибок: "файл не найден", он скорее всего бросит это занятие, даже если будет работать поиск. - -Перед нами тот случай, когда архитектура ПО относительно технических аспектов обладает более низким приоритетом по сравнению с психологией восприятия, которая ставит три задачи упорядочивания ошибок по аспектам: - -1. Важность: критическая или нормальная. -2. Источник: где возникла ошибка: система, класс, функция. -3. Причинность (кто виноват): пользователь, внешняя система, программист. - -## Инфраструктура исключений - -С тех пор, как в языки программирования (и конечно же в Операционные Системы) пришли исключения, появилось понятие потока ошибок: как отдельного потока управления. - -Исключения дали возможность избежать "избыточного кода" при обработке ошибок: блок программы может реагировать только на тот тип исключений, который интересует его. Поэтому создание хорошей инфраструктуры исключений (или скажем структуры классов) является приоритетной задачей. - -То есть программист обязан определить классы исключений, так как они будут участвовать в логике. Такие классы нельзя считать "избыточным кодом" (хотя и целевым тоже). - -Что если, к задаче создания инфраструктуры исключений добавить решение вышестоящих вопросов: - -1. Определение степени критичности. -2. Определение структуры журналируемых данных. -3. Определение источника возникновения. -4. Определение аспекта причинности. -5. Определение кода журналирования. - -И избавиться от проблем: - -1. Код журналирования уйдёт из целевого кода. -2. Тот, кто использует исключение больше не будет думать о его аспектах. -3. Код определения структуры, журналирования и аспектов находится в одном месте, а не разбросан по всему проекту. -4. А значит: код исключения теперь можно реализовать и изменить в любой момент. - -## Структурирование данных - -Как правило, исключение позволяет задать всего два вида пользовательских данных: - -1. Текст исключения. -2. Код исключения. - -Если программисту нужно нечто большее, он может унаследовать от `Exception` свой класс, и сделать так: +Поэтому, создавая новый класс исключения, необходимо учитывать, +что он должен содержать метаданные, которые будут использоваться для логирования. ```php - class MyException() - { - private $counter; - - public function __construct(Object $object) - { - $this->counter = $object->get_counter(); - parent::__construct('Error Object Format for '.$object->get_name()); - } - - // Специальный метод - public function get_counter() - { - return $this->counter; - } - } - -... - // Теперь можно использовать так: - $object = new Object(); - … - throw new MyException($object); - -... - // где-то в другой галактике поймали исключение - catch(MyException $e) - { - if($e->get_counter() === 0) - ... - } -``` - -Такой подход даёт следующие плюсы: - -1. Для внешнего кода появляется возможность обрабатывать только исключение `MyException`. -2. Теперь не нужно помнить текст исключения. -3. Целевой код выглядит проще и чище. -4. Вместе с `MyException` можно передавать дополнительную информацию об ошибке. - -Теперь вернёмся к вопросу журналирования. Если исключение попадёт в обычный журнал, то как правило сохранятся только сообщение, код ошибки, и `trace`. Но в `trace` очень много данных, и обычно они оказываются не нужны. А вот как бы сделать так, чтобы с одной стороны данные были упорядочены, а с другой стороны - в них не было бы лишней информации. - -Можно текст исключения формировать в *json*, тогда уже после записи в журнал мы всегда сможем проанализировать данные. Но тогда теряется текст исключения, и мы вторгаемся на поле игры Языка Программирования. - -Интереснее выглядит вариант при котором данные размещаются в отдельном свойстве, которое будет ассоциативным массивом. Почему ассоциативный массив? Потому что его просто расширять. Массив не обязан содержать какие-то конкретные ключи. Разные исключения могут определять свои ключи, а с точки зрения журнала - формат массива не имеет значения. - -В этом специальном свойстве будут храниться только самые важные данные, которые интересны при рассмотрении исключения. Эти данные можно использовать и во время выполнения. Главное, что для ассоциативного массива возможен обобщённый код, который будет работать с различными исключениями, но сохранять структуру дополнительных данных. - -## Журналирование - -Допустим, что структура обобщённого исключения выглядит так: - -- `message` - сообщение; -- `code` - код ошибки; -- другие стандартные данные вроде `line`, `file`; -- `data` - дополнительные данные: всегда ассоциативный массив. - -Осталось понять: как это журналировать? - -Можно журналировать прямо в целевом коде, но мы уже говорили, что данный подход изначально некорректен. Можно журналировать в обработчике "необработанных" исключений, но тогда, что делать с такими исключениями, которые были пойманы? Ведь возможна ситуация, когда критическую ошибку просто подавили. Программа отказывает работать, но уже не понятно отчего. Остаётся единственный вариант: журналировать исключение прямо в -конструкторе. +final class UserNotAllowed extends \IfCastle\Exceptions\BaseException +{ + protected string $template = 'User {user} from {ip} is not allowed'; + protected array $tags = ['user', 'auth']; -У этого решения есть свои недостатки. Главный из них - невозможность изоляции кода регистрации исключения: этот код должен быть представлен глобальным объектом (классом или функцией). Этот недостаток так же намекает о том, что данный механизм следует поддерживать на уровне языка программирования, и что подобное решение относительно "совершенной чистоты кода" - костыль. - -Однако на практике, этот недостаток не оказывается настолько страшным: - -1. Во-первых сложно найти системы, где исключения имеют больше одной точки сбора. -2. Во-вторых, если и нужна другая точка сбора, то её можно перегрузить в дочернем классе. - -Невозможно будет лишь сделать что-то такое: - -```future - - ... - // где-то в далёкой галактике… - function Destroy_All_Humans(CErectus human) + public function __construct(string $user, string $ip) { - throw new Divide_by_zero(human); - } - ... - - // Определение потока ошибок - define error_stream System - { - // код помощи человекам - Exception Rescue_People - { - … - } - } - - // Включение зоны ошибок - @error_stream System - { - // Исключение попадает в System - Destroy_All_Humans(); - - @error_stream My - { - // Исключение попадает в My - Destroy_All_Humans(); - } + parent::__construct([ + 'user' => $user, + 'ip' => $ip + ]); } ``` -Остаётся так же ещё один вопрос: что делать для тех исключений, которые не журналируются сами, когда их нужно подавить, но записать в журнал? Выходит, не получиться уйти от кода логирования в целевом коде? - -Тут можно использовать принцип приведения: если у нас есть алгоритм для ситуации А, но мы находимся в B, то нам иногда проще свести B в А[^4]. На практике это выглядит как создание контейнера для исключения: +В данном примере, класс `UserNotAllowed` содержит шаблон сообщения и теги, которые будут использоваться для логирования. +Когда это исключение попадёт в логгер, он сможет использовать шаблон сообщения и теги для формирования сообщения об ошибке. ```php - try - { - ... - } - catch(\Exception $e) - { - // Привели исключение к нужному типу данных - new LoggableException($e); - // А можно было ещё и указать аспект - new SystemException($e); - } + $exception = new UserNotAllowed('admin', '127.0.0.1'); + $logger->error($exception); ``` -Получается логичный код, который кратко выражает суть: - -1. Создали исключение `new`: значит есть проблема. -2. Не использовали `throw`: значит программа может работать дальше. - -При этом никакого кода журналирования! - -В остальном данное решение полно важных достоинств: - -1. Исключение будет журналировано даже, если будет подавлено. -2. Код журналирования находится не в основном потоке программы. -3. Каждое исключение способно решать: нужно ли ему журналироваться или нет. - -Третий пункт является весьма важным, так как позволяет повысить качество журнала: журнал содержит только на самом деле нужные данные. - -## Аспекты причинности - -Извечный "русский вопрос": "кто виноват и что делать" так же неплохо звучит на паперти потока ошибок. Как только становится ясно, что виноватых больше чем один - виноватым становится "никто"[^5]. - -Мне удалось наблюдать не раз замечательную эпопею, когда причиной сбоя программы были административные проблемы вроде прав записи в файловой системе. В результате всё остальное заранее списывалось на эту проблему. Администраторы говорили: "всё дело в вашей программе". Программисты: "нет - у вас кривые настройки". - -Этого можно было бы избежать, если предоставить администраторам специальный журнал ошибок, причиной которых является "система". В этом случае, вопросов: "кто виноват, и что делать" возникало бы на порядок меньше. - -Разделение ошибок по причинам или источникам их возникновения - идея не новая. Но отчего-то незаслуженно забываемая[^6]. Кроме того, эта идея часто реализована в худшем варианте: когда причин ошибок больше, чем нужно. Мы уже говорили об этом раньше при обсуждении "конца света": человек хорошо реагирует только на два сигнала. - -Поэтому я предлагаю ввести всего два аспекта причинности: - -1. Системные ошибки - ошибки вызванные системой, с которой взаимодействует программа. -2. Ошибки выполнения - ошибки вызванные внешней средой, которая взаимодействует с программой. - -А третий аспект ошибок (так сказать номер 0): ошибки по вине программиста. Будем считать, что таких ошибок быть не может :). Поэтому базовых аспекта всего лишь два. - -Всё это хорошо демонстрируется на схеме: - - [Env] -> (Program) -> [System] - | | | - RuntimeErrors Errors SystemErrors - -где: - -- *Env* - внешняя среда, которая работает с *Program*; -- *Program* - то, что мы создали; -- *System* - ОС, или другие программы, с которыми работает *Program*. - -`RuntimeErrors` может использоваться и для ошибок конфигурации. Хотя конфигурация обычно является частью системы (`Program`), и часто создаётся самими программистами. Использование аспекта остаётся оправданным по той причине, что ошибка не относится к коду программы. Либо, если группа программистов, создающая конфигурацию, является внешней по отношению к авторам кода, тогда конфигурацию следует считать "внешними данными". - -## Степень критичности - -Как уже говорилось имеет смысл выделять всего две степени критичности ошибки: - -1. Фатальные ошибки. -2. Обычные ошибки. - -Фатальной считается ошибка (исключение), если она соответствует трём критериям одновременно: - -1. Причина серьёзна, а следствием является полная неработоспособность программы. -2. Ошибка будет воспроизводится постоянно (с высокой вероятностью). -3. Для устранения причин потребуется вмешательство специалиста. - -Если исключение не попадает хотя бы под один критерий, оно не может считаться фатальным. - -Фатальные исключения обрабатываются иначе, чем обычные ошибки: - -1. Код обработки следует делать "тихим" (без ошибок и других исключений), простым и тщательно тестированным. -2. Код обработки может находиться в условиях нехватки ресурсов (дисковое пространство, память, процессорное время). -3. Программа может запретить выполнение своих сервисов, пока проблема не будет решена (помогает выйграть ресурсы и остановить потерю данных). -4. Программа может запустить специальный процесс для анализа и решения проблем. - -В вашей программе не должно быть много видов "фатальных ошибок". В противном случае, фатальные ошибки будут пониматься как обычные. Вы обязаны подходить с особым недоверием при внедрении новой фатальной ошибки. - -## Источник ошибок - -Кроме записи типа исключения для журнала ошибок так же необходимо логирование источника исключения. В `PHP` вроде бы такую задачу призваны решать методы `Exception::getFile()`, `Exception::getLine()`. Однако они весьма далёки от совершенства, так как зависят от файловой структуры. - -Более надёжным, переносимым методом указания источника ошибок следует считать полное имя класса. Начиная с `PHP 5.3` оно содержит так же и `namespace`, а значит, позволяет указать не только класс возникновения ошибки, но и систему классов, в которой класс находится. - -Это оказывается весьма удобным, особенно когда `namespace` повторяет структуру папок и файлов с исходным кодом. В этом случае информация `Exception::getFile()` не имеет никакого смысла. - -## Отладочная информация - -С целью отладки иногда требуется записать в журнал такие данные, которые в обычном режиме не нужны. Поэтому было бы правильным внести в нашу парадигму: отладочную информацию. Её так же стоит представлять в виде ассоциативного массива, или же в виде строки отформатированных данных. - -Так как отладочная информация нужна только в момент тестирования, следует предусмотреть возможность простого отключения и включения режима. А так же возможность включения режима только для некоторых классов. Это позволит собирать отладочные данные только нужного типа, и причём на "рабочей системе". +Если в качестве системы логирования вы используете OpenTelemetry, +в таком случае метаданные исключения будут использоваться для формирования атрибутов, +которые попадут в трейсер вместе с тегами и шаблоном сообщения. --------- -[^1]: Я называю это НЕИИ: непрограммируемый искусственный интеллект :) -[^2]: Эту причину стоит считать серьёзной, так как она является дизмотивирующей. -[^3]: Непереводимая и неповторимая игра слов :) -[^4]: Как в одном хорошем анекдоте про алгоритм заварки чая: если чайник уже полный, нужно просто вылить воду из чайника и начать с начала :). -[^5]: Или же мифический "козел отпущения" -[^6]: Иногда даже кажется, что люди склонны забывать всё хорошее, но отлично запоминать дурость. diff --git a/docs/03-BaseException.md b/docs/03-BaseException.md index 503cac0..1ccb965 100644 --- a/docs/03-BaseException.md +++ b/docs/03-BaseException.md @@ -1,9 +1,5 @@ # BaseException -`BaseException` - базовый класс библиотеки, от которого наследуются исключения. Он содержит реализацию всех основных методов, определяет все основные свойства. - -`BaseExceptionI` - базовый интерфейс для всех объектов, которые поддерживают парадигму библиотеки. Этими объектами могут быть не только исключение, что делает возможным участие пользовательских объектов, не предназначенных для `throw`, но предназначенных для журналирования. - ## Конструктор Конструктор `BaseException` имеет три режима работы: @@ -12,14 +8,15 @@ 2. Режим структурированных данных. 3. Режим контейнера. -Наследуемые исключения могут так же прозрачно поддерживать эти режимы, а могут закрывать их своим конструктором. +Наследуемые исключения могут так же прозрачно поддерживать эти режимы, а могут перекрывать их своим конструктором. -Например, класс `UnexpectedValue`, может вести себя как `BaseException`, если параметр `$name` будет иметь тип отличный от скаляра. +Например, класс `UnexpectedValue`, может вести себя как `BaseException`, +если параметр `$name` будет иметь тип отличный от скаляра. ```php class UnexpectedValue extends LoggableException { - public function __construct($name, $value = null, $rules = null) + public function __construct(string|array $name, mixed $value = null, string $rules = null) { if(!is_scalar($name)) { @@ -28,29 +25,28 @@ } parent::__construct - ( - array - ( - 'message' => 'Unexpected value', - 'name' => $name, - 'value' => self::truncate($value), - 'rules' => $rules, - 'type' => self::get_value_type($value) - ) - ); + ([ + 'message' => 'Unexpected value', + 'name' => $name, + 'value' => self::truncate($value), + 'rules' => $rules, + 'type' => self::get_value_type($value) + ]); } } ``` -В остальных случаях, `UnexpectedValue` фомирует данные самостоятельно. - ## Шаблоны сообщений -Исключения содержат свойство `message`, которое в общем случае является уникальным для каждого экземпляра класса, что исключает возможность интернационализации. Также с точки зрения разделения знаний лучше не смешивать описание ошибки с данными из контекста. +Исключения содержат свойство `message`, которое в общем случае является уникальным для каждого экземпляра класса, +что исключает возможность интернационализации. +Также с точки зрения разделения знаний лучше не смешивать описание ошибки с данными из контекста. Шаблоны сообщений решают данную задачу, определяя текст шаблона ошибки, который формирует сообщение `message`. -Так как базовый класс `\Exception` запрещает переопределять метод `getMessage()`, шаблон формируется в отдельном свойстве `template` и может быть инициализирован через конструктор `BaseException`. Однако правилом хорошего тона является определение шаблона в дочернем классе, при помощи переопределения свойства: +Так как базовый класс `\Exception` запрещает переопределять метод `getMessage()`, +шаблон формируется в отдельном свойстве `template` и может быть инициализирован через конструктор `BaseException`. +Однако правилом хорошего тона является определение шаблона в дочернем классе, при помощи переопределения свойства: ```php class UnexpectedValueType extends LoggableException @@ -58,12 +54,14 @@ class UnexpectedValueType extends LoggableException protected $template = 'Unexpected type occurred for the value {name} and type {type}. Expected {expected}'; ``` -Формат строки шаблона соответсвует правилам [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). +Формат строки шаблона соответствует правилам [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). Если исключение определяет шаблон, тогда конструктор `BaseException` работает иначе: -1. *Placeholders* шаблона заменяются данными из контекста, и передаются в конструктор `\Exception`. Таким образом, метод `getMessage()` вернёт полный текст ошибки. -2. Если в конструктор `BaseException` передано свойство `message`, оно воспринимается как дополнительное сообщение, и присоединятся к результирующему сообщению через точку. Например: +1. *Placeholders* шаблона заменяются данными из контекста, и передаются в конструктор `\Exception`. +Таким образом, метод `getMessage()` вернёт полный текст ошибки. +2. Если в конструктор `BaseException` передано свойство `message`, +оно воспринимается как дополнительное сообщение, и присоединятся к результирующему сообщению через точку. Например: ```php @@ -82,20 +80,21 @@ class UnexpectedValueType extends LoggableException ## Наследование -В большенстве случаев дочерний класс переопределяет только конструктор, так как ему нужно сформировать данные исключения. +В большинстве случаев дочерний класс переопределяет только конструктор, так как ему нужно сформировать данные исключения. -Если дочернему классу требуется изменить поведение исключения, он может изменять унаследованные свойства. В данном случае - это поведение является нормальным. +Если дочернему классу требуется изменить поведение исключения, он может изменять унаследованные свойства. +В данном случае - это поведение является нормальным. Упрощённый алгоритм `BaseException::__construct`: 1. Анализировать входные данные. 2. Вызвать родительский конструктор `\Exception`. -3. Если `BaseException::is_loggable` журнализировать исключение. -4. Если `BaseException::is_fatal` вызвать обработчик фатальных исключений. +3. Если `BaseException::isLoggable` финализировать исключение. +4. Если `BaseException::isFatal` вызвать обработчик фатальных исключений. Конструктор может изменять любые свойства после своего вызова. Поэтому, если вам нужно модифицировать свойства класса окончательно, делайте это после вызова базового конструктора. -Изменение свойств флажков (с префиксом `is_`) вызывает изменение в поведении базового конструктора. +Изменение свойств флажков (с префиксом `is`) вызывает изменение в поведении базового конструктора. Например, вот так можно включить журналирование: @@ -109,7 +108,7 @@ class UnexpectedValueType extends LoggableException * * @var boolean */ - protected $is_loggable = true; + protected $isLoggable = true; } ``` @@ -118,22 +117,24 @@ class UnexpectedValueType extends LoggableException ```php class MyException extends BaseException { - protected $is_fatal = true; + protected $isFatal = true; } ``` -Класс `BaseException` не журналируется и не имеет аспектов. Поэтому для наследования удобно иметь дополнительные "базовые исключения": +Класс `BaseException` не журналируется и не имеет аспектов. +Поэтому для наследования удобно иметь дополнительные "базовые исключения": 1. `LoggableException` - для исключений, которые журналируются. 2. `SystemException` - для исключений с аспектом "системное". 3. `RuntimeException` - для исключений с аспектом "runtime". 4. `FatalException`, `FatalRuntimeException`, `FatalSystemException` - для фатальных исключений. -(подробнее о журнализировании в разделе: [Журналирование][1]) +(подробнее о морализировании в разделе: [Журналирование][1]) ## Рекомендации по формированию данных -Обратите внимание, что конструктор `BaseException` не изменяет данные, которые вы передаёте ему. Эту работу обязаны делать дочерние исключения. +Обратите внимание, что конструктор `BaseException` не изменяет данные, которые вы передаёте ему. +Эту работу обязаны делать дочерние исключения. Хорошо придерживаться рекомендаций: @@ -144,28 +145,40 @@ class UnexpectedValueType extends LoggableException ### Не хранить в исключении объекты -Исключения могут попадать в журнал, и хранится в памяти намного дольше, чем объекты, переданные в исключение. Таким образом, вы будете раздувать приложение, так как сборщик мусора не сможет освободить память. Если для Web-скриптов это не актуально, то для фоновых заданий - скорее всего. +Исключения могут попадать в журнал, и хранится в памяти намного дольше, чем объекты, переданные в исключение. +Таким образом, вы будете раздувать приложение, так как сборщик мусора не сможет освободить память. +Если для Web-скриптов это не актуально, то для фоновых заданий - скорее всего. ### Усечение данных -Свойство `BaseException::data` попадает в журнал. Хотя данные, которые попадают в журнал сохраняют структуру, и могут быть десериализированы заново, не стоит использовать большие массивы данных. Это не только замедляет процесс обработки журнала, но и создаёт ненужную избыточность. Если в самом деле необходимо сохранять большие массивы данных, лучше использовать отладочный режим. +Свойство `BaseException::data` попадает в журнал. +Хотя данные, которые попадают в журнал, сохраняют структуру, и могут быть десериализированы заново, +не стоит использовать большие массивы данных. +Это не только замедляет процесс обработки журнала, но и создаёт ненужную избыточность. +Если в самом деле необходимо сохранять большие массивы данных, лучше использовать отладочный режим. Для усечения данных можно использовать методы: -- `BaseException::get_type()`; +- `BaseException::getType()`; - `BaseException::truncate()`. ### Использование в data базовых типов -Это требование имеет с одной стороны тот же смысл, что и "Не хранить объекты в исключении". Но главная причина иная. Свойство `data` может участвовать в процессе сериализации исключения. А объекты не всегда можно правильно сериализировать/десериалировать. Хотя можно воспользовать интерфейсом `Serializable` - это не самая хорошая идея, так как целью сериализации могут быть другие форматы, отличные по сути от `Serializable`. +Это требование имеет с одной стороны тот же смысл, что и "Не хранить объекты в исключении". +Но главная причина иная. Свойство `data` может участвовать в процессе сериализации исключения. +А объекты не всегда можно правильно сериализировать/десериалировать. +Хотя можно воспользовать интерфейсом `Serializable` - это не самая хорошая идея, +так как целью сериализации могут быть другие форматы, отличные по сути от `Serializable`. Если вы хотите получить возможность легко сериализировать исключения - пытайтесь строго следовать этому правилу. ## Отладочные данные -Для сохранения отладочных данных, `BaseException` предоставляет метод `set_debug_data()`. Этот метод имеет атрибут `protected`, а значит предназначен только для внутреннего использования. +Для сохранения отладочных данных, +`BaseException` предоставляет метод `set_debug_data()`. +Этот метод имеет атрибут `protected`, а значит предназначен только для внутреннего использования. -Алгоритм `BaseException::set_debug_data()`: +Алгоритм `BaseException::setDebugData()`: 1. Проверить, активен ли режим отладки. 2. Если да, перевести данные в строку, и сохранить их. @@ -184,13 +197,13 @@ class UnexpectedValueType extends LoggableException ([ 'message' => 'Unexpected value', 'name' => $name, - 'type' => self::get_value_type($value) + 'type' => self::getValueType($value) ]); } } ``` -Используя свойство `is_debug`, вы можете насильно записать данные, в независимости от того, включён ли режим отладки или нет: +Используя свойство `isDebug`, вы можете намеренно записать данные, в независимости от того, включён ли режим отладки или нет: ```php class UnexpectedValue extends LoggableException @@ -212,7 +225,8 @@ class UnexpectedValueType extends LoggableException } ``` -При этом отладочные данные запишутся только для вашего исключения. Это позволяет быстро ввести отладочный режим даже на рабочей системе, только в необходимом месте. +При этом отладочные данные запишутся только для вашего исключения. +Это позволяет быстро ввести отладочный режим даже на рабочей системе, только в необходимом месте. Таким же образом, можно и отключить отладочный режим: @@ -222,15 +236,18 @@ class UnexpectedValueType extends LoggableException // (если конечно не переопределят его явно) class NoDebugException extends LoggableException { - protected $is_debug = false; + protected $isDebug = false; } ``` ## Сериализация -Кроме основных методов `BaseException` поддерживает сериализацию/десериализацию. Это может быть полезно для маршалинга исключений через удалённые сервисы, сохранения исключений на диск и прочего, где обычно используется сериализация. +Кроме основных методов `BaseException` поддерживает сериализацию/десериализацию. +Это может быть полезно для маршалинга исключений через удалённые сервисы, +сохранения исключений на диск и прочего, где обычно используется сериализация. -Целевым форматом сериализации является асоциативный массив. Массив выбран потому, что его легко преобразовать в любой другой формат: `json`, `xml`, `phpserialize`, etc. +Целевым форматом сериализации является асоциативный массив. +Массив выбран потому, что его легко преобразовать в любой другой формат: `json`, `xml`, `phpserialize`, etc. Формат массива: @@ -255,7 +272,8 @@ class UnexpectedValueType extends LoggableException ## Особенности -Следующие методы `BaseException` существуют потому, что стандартные методы `PHP` `\Exception` объявлены как `final`, но поведение их не соответствует общей парадигме `BaseException`. +Следующие методы `BaseException` существуют потому, что стандартные методы `PHP` `\Exception` объявлены как `final`, +но поведение их не соответствует общей парадигме `BaseException`. ### Определение источника исключения @@ -269,7 +287,11 @@ class UnexpectedValueType extends LoggableException ]; ``` -Метод `BaseException::get_source()` используется при журналировании вместо метода `BaseException::getFile()`, потому что определение источника по имени класса является более естественным методом относительно устройства языка. После введения `namespace` и `autoload` реальная структура файлов больше не имеет большого значения, а информация об `namespace` сохраняется и тогда, когда весь код объединяется в один файл. +Метод `BaseException::getSource()` используется при журналировании вместо метода +`BaseException::getFile()`, +потому что определение источника по имени класса является более естественным методом относительно устройства языка. +После введения `namespace` и `autoload` реальная структура файлов больше не имеет большого значения, +а информация об `namespace` сохраняется и тогда, когда весь код объединяется в один файл. Обратите внимание, что порядок ключей в массиве `source` имеет значение, и он создан таким образом, что если выполнить слияние массива в строку, то вы получите строковое указание источника: @@ -301,7 +323,8 @@ class UnexpectedValueType extends LoggableException ### Определение вложенного исключения -`BaseException` создаёт контейнеры для любых объектов, которые поддерживают интерфейс `BaseExceptionI`. Этот приём позволяет оборачивать в исключения другие объекты, которые имеют схожее поведение, но не являются `PHP` исключениями. +`BaseException` создаёт контейнеры для любых объектов, которые поддерживают интерфейс `BaseExceptionInterface`. +Этот приём позволяет оборачивать в исключения другие объекты, которые имеют схожее поведение, но не являются `PHP` исключениями. Однако `\Exception::$previous` может быть только дочерним объектом от `\Exception`. Чтобы обойти это органичение, `BaseException` помещает объект `BaseExceptionI` в свойство `data` (в контейнере это свойство не используется для данных). diff --git a/docs/05-Registry.md b/docs/05-Registry.md index f2c2c8b..f76af1f 100644 --- a/docs/05-Registry.md +++ b/docs/05-Registry.md @@ -8,7 +8,7 @@ static public function set_registry_storage(StorageI $storage) ``` -Интерфейс `StorageI` содержит всего несколько методов, и позволяет влиять на ход регистрации исключений. +Интерфейс `StorageInterface` содержит всего несколько методов, и позволяет влиять на ход регистрации исключений. Дополнительное расширение функциональности `Registry` можно получить, используя методы: diff --git a/docs/06-FatalException.md b/docs/06-FatalException.md index 52ae520..32a6cd9 100644 --- a/docs/06-FatalException.md +++ b/docs/06-FatalException.md @@ -2,7 +2,7 @@ Аспект "Фатальная ошибка" реализован в виде свойства `is_fatal`, а так же публичного метода: `is_fatal()`. Интересно заметить, что по сравнению с флагом `is_loggable()` у флага `is_fatal` нет возможности сброса (разве что изнутри класса). -Так как `is_fatal` - это свойство, то фатальным может стать любое исключение в любой момент времени: +Так как `isFatal` - это свойство, то фатальным может стать любое исключение в любой момент времени: ```php try diff --git a/docs/07-Best_practices.md b/docs/07-Best_practices.md deleted file mode 100644 index ce2e0ce..0000000 --- a/docs/07-Best_practices.md +++ /dev/null @@ -1,27 +0,0 @@ -# Best practices - -## Пример явного логирования ошибки аспекта Runtime - -```php - - // - // Redefine error_handler for preg_match_all(). - // - $old_handler = set_error_handler(function ($errno, $errstr) - { - new RuntimeException - ([ - 'message' => 'Preg error: '.$errstr, - 'code' => $errno, - 'preg' => $this->rule - ]); - }); - $matches = []; - $res = preg_match_all($this->rule, $query, $matches); - set_error_handler($old_handler); - - if(!$res) - { - return false; - } -```