diff --git a/.gitignore b/.gitignore
index a67d42b..aa5a2af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
composer.phar
/vendor/
+/.phpunit.cache
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
diff --git a/README.md b/README.md
index a10cfa1..cfa699f 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@ Extension for PHPStan for better support for Craft CMS. The following features a
- Dependency injection container support for `Craft::$container->get()`
- Recognises custom field handles as properties on `Element` and `ElementQuery`, including handle overrides from entry-type field layouts (read from your project config)
- Validates the `action` value of Twig `actionInput()` calls against discovered controller routes (including shorthand routes for controller default actions)
+- Detects Twig N+1 query patterns and related performance smells (relational access in loops, queries built in loops, `|length` on queries, unbounded `.all()`), with eager-load (`.with([...])`) and Craft 5 `.eagerly()` suppression
## Install
@@ -18,6 +19,10 @@ Via Composer
$ composer require --dev jensderond/phpstan-craftcms
```
+The Twig checks require `twig/twig` ^3.27. Craft pins Twig to a specific minor
+(e.g. Craft 5.10 uses `~3.27.0`), so projects on an older Craft 5.x release that
+locks Twig below 3.27 need to update Craft before installing this version.
+
## Usage
Add `phpstan-craftcms` to the project `phpstan.neon` / `phpstan.neon.dist`:
@@ -42,12 +47,61 @@ parameters:
- %currentWorkingDirectory%/modules
- %currentWorkingDirectory%/plugins
handleMap: []
+ craftTemplateScan:
+ excludeDirectories:
+ - vendor
+ - node_modules
+ craftTwigPerformance:
+ enabled: true
+ templatePaths: %craftActionInput.templatePaths%
+ checks:
+ nPlusOne: true
+ nestedRelationAll: true
+ queryInLoop: true
+ lengthOnQuery: true
+ unboundedAll: false
```
- `yii2.config_path` — path to your Yii/Craft application config used to build the service and route maps.
- `craftcms.projectConfigPath` — path to the Craft project config directory; used to collect custom field handles and entry-type handle overrides.
- `craftActionInput.templatePaths` — directories scanned for Twig `actionInput()` calls.
- `craftActionInput.handleMap` — optional map of additional handle aliases used when resolving `actionInput()` values to controllers.
+- `craftTemplateScan.excludeDirectories` — directory **names** pruned from the template walk (shared by the action-input and performance scans). Defaults to `vendor` and `node_modules`, so third-party templates a package bundles (Craft's own control-panel templates, other plugins' example/asset templates) are not analysed when a scanned path contains them. Add more names (e.g. `tests`) to skip further trees.
+
+### Twig performance checks
+
+`craftTwigPerformance.checks` toggles each check; `unboundedAll` is off by default
+(it is often intentional). Suppress a check project-wide via `ignoreErrors` using
+its identifier:
+
+- `craftcms.twigNPlusOne`
+- `craftcms.twigNestedRelationAll`
+- `craftcms.twigQueryInLoop`
+- `craftcms.twigLengthOnQuery`
+- `craftcms.twigUnboundedAll`
+
+Limitations: analysis is per-template — it does not follow loop variables across
+`{% include %}`, macros, or block boundaries. Loop-source eager-loading is detected
+inline or one `{% set %}` back. `.with(...)` is honored only for literal string
+arrays; dynamic arguments suppress the finding. `|length`-on-query detection is a
+best-effort static heuristic. Eager-load suppression recognizes both
+`.with([...])` and Craft 5's `.eagerly()`. Relation checks
+(`twigNPlusOne`/`twigNestedRelationAll`) fire only for loops that iterate element
+query results: a loop over a static array/hash literal — directly, via `{% set %}`,
+or through nested loops — yields plain values, so an attribute that happens to
+share a relation field's handle (e.g. `font.file` over a hash literal) is not
+flagged.
+
+#### Result cache and template changes
+
+The Twig checks scan the template tree directly, outside PHPStan's per-file
+analysis. PHPStan's result cache is normally keyed on the analysed **PHP**
+files (and the config) only, so this extension registers a result-cache meta
+extension that folds a hash of every discovered template's path and contents
+into the cache metadata. Editing, adding, or removing a `.twig` file changes
+that hash, which invalidates the result cache and triggers a full re-analysis —
+no manual `clear-result-cache` needed. Template changes are picked up by a
+plain `phpstan analyse`, locally and in CI, just like PHP changes.
## Credits
diff --git a/composer.json b/composer.json
index 9b5b414..9870e60 100644
--- a/composer.json
+++ b/composer.json
@@ -1,13 +1,15 @@
{
"name": "jensderond/phpstan-craftcms",
"description": "CraftCMS extension for PHPStan",
- "version": "1.3.0",
+ "version": "1.4.0",
"require": {
- "phpstan/phpstan": "^2.1"
+ "phpstan/phpstan": "^2.1",
+ "twig/twig": "^3.27"
},
"require-dev": {
- "craftcms/cms": "~5",
- "laravel/pint": "^1.25"
+ "craftcms/cms": "^5.10.8",
+ "laravel/pint": "^1.25",
+ "phpunit/phpunit": "^11.5"
},
"license": "MIT",
"autoload": {
@@ -15,6 +17,11 @@
"Jensderond\\PhpstanCraftcms\\": "src/"
}
},
+ "autoload-dev": {
+ "psr-4": {
+ "Jensderond\\PhpstanCraftcms\\Tests\\": "tests/"
+ }
+ },
"authors": [
{
"name": "Jens de Rond",
@@ -22,7 +29,8 @@
}
],
"scripts": {
- "lint": "pint"
+ "lint": "pint",
+ "test": "phpunit"
},
"config": {
"allow-plugins": {
diff --git a/composer.lock b/composer.lock
index bbbb088..3e0d9e4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "22782ed2364ff517cf8d976c4ecdc263",
+ "content-hash": "6793668d829c89ff56a79e634dc62851",
"packages": [
{
"name": "phpstan/phpstan",
@@ -58,158 +58,198 @@
}
],
"time": "2025-10-10T14:14:11+00:00"
- }
- ],
- "packages-dev": [
+ },
{
- "name": "bacon/bacon-qr-code",
- "version": "2.0.8",
+ "name": "symfony/deprecation-contracts",
+ "version": "v3.7.1",
"source": {
"type": "git",
- "url": "https://github.com/Bacon/BaconQrCode.git",
- "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22"
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22",
- "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/f3202fa1b5097b0af062dc978b32ecf63404e31d",
+ "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d",
"shasum": ""
},
"require": {
- "dasprid/enum": "^1.0.3",
- "ext-iconv": "*",
- "php": "^7.1 || ^8.0"
- },
- "require-dev": {
- "phly/keep-a-changelog": "^2.1",
- "phpunit/phpunit": "^7 | ^8 | ^9",
- "spatie/phpunit-snapshot-assertions": "^4.2.9",
- "squizlabs/php_codesniffer": "^3.4"
- },
- "suggest": {
- "ext-imagick": "to generate QR code images"
+ "php": ">=8.1"
},
"type": "library",
- "autoload": {
- "psr-4": {
- "BaconQrCode\\": "src/"
+ "extra": {
+ "thanks": {
+ "url": "https://github.com/symfony/contracts",
+ "name": "symfony/contracts"
+ },
+ "branch-alias": {
+ "dev-main": "3.7-dev"
}
},
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-2-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Ben Scholzen 'DASPRiD'",
- "email": "mail@dasprids.de",
- "homepage": "https://dasprids.de/",
- "role": "Developer"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "BaconQrCode is a QR code generator for PHP.",
- "homepage": "https://github.com/Bacon/BaconQrCode",
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
"support": {
- "issues": "https://github.com/Bacon/BaconQrCode/issues",
- "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.1"
},
- "time": "2022-12-07T17:46:57+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-06-05T06:23:12+00:00"
},
{
- "name": "brick/math",
- "version": "0.13.1",
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.37.0",
"source": {
"type": "git",
- "url": "https://github.com/brick/math.git",
- "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04"
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "141046a8f9477948ff284fa65be2095baafb94f2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/brick/math/zipball/fc7ed316430118cc7836bf45faff18d5dfc8de04",
- "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2",
+ "reference": "141046a8f9477948ff284fa65be2095baafb94f2",
"shasum": ""
},
"require": {
- "php": "^8.1"
+ "php": ">=7.2"
},
- "require-dev": {
- "php-coveralls/php-coveralls": "^2.2",
- "phpunit/phpunit": "^10.1",
- "vimeo/psalm": "6.8.8"
+ "provide": {
+ "ext-ctype": "*"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
},
"type": "library",
+ "extra": {
+ "thanks": {
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
+ }
+ },
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Brick\\Math\\": "src/"
+ "Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "Arbitrary-precision arithmetic library",
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
"keywords": [
- "Arbitrary-precision",
- "BigInteger",
- "BigRational",
- "arithmetic",
- "bigdecimal",
- "bignum",
- "bignumber",
- "brick",
- "decimal",
- "integer",
- "math",
- "mathematics",
- "rational"
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
],
"support": {
- "issues": "https://github.com/brick/math/issues",
- "source": "https://github.com/brick/math/tree/0.13.1"
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0"
},
"funding": [
{
- "url": "https://github.com/BenMorel",
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/nicolas-grekas",
"type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
}
],
- "time": "2025-03-29T13:50:30+00:00"
+ "time": "2026-04-10T16:19:22+00:00"
},
{
- "name": "cebe/markdown",
- "version": "1.2.1",
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.38.2",
"source": {
"type": "git",
- "url": "https://github.com/cebe/markdown.git",
- "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86"
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/cebe/markdown/zipball/9bac5e971dd391e2802dca5400bbeacbaea9eb86",
- "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6",
+ "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6",
"shasum": ""
},
"require": {
- "lib-pcre": "*",
- "php": ">=5.4.0"
+ "ext-iconv": "*",
+ "php": ">=7.2"
},
- "require-dev": {
- "cebe/indent": "*",
- "facebook/xhprof": "*@dev",
- "phpunit/phpunit": "4.1.*"
+ "provide": {
+ "ext-mbstring": "*"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
},
- "bin": [
- "bin/markdown"
- ],
"type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "1.2.x-dev"
+ "thanks": {
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "cebe\\markdown\\": ""
+ "Symfony\\Polyfill\\Mbstring\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -218,121 +258,1993 @@
],
"authors": [
{
- "name": "Carsten Brandt",
- "email": "mail@cebe.cc",
- "homepage": "http://cebe.cc/",
- "role": "Creator"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "A super fast, highly extensible markdown parser for PHP",
- "homepage": "https://github.com/cebe/markdown#readme",
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
"keywords": [
- "extensible",
- "fast",
- "gfm",
- "markdown",
- "markdown-extra"
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
],
"support": {
- "issues": "https://github.com/cebe/markdown/issues",
- "source": "https://github.com/cebe/markdown"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2"
},
- "time": "2018-03-26T11:24:36+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-05-27T06:59:30+00:00"
},
{
- "name": "commerceguys/addressing",
- "version": "v2.2.4",
+ "name": "twig/twig",
+ "version": "v3.27.1",
"source": {
"type": "git",
- "url": "https://github.com/commerceguys/addressing.git",
- "reference": "ea826dbe5b3fe76960073a2167d5cf996c811cda"
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "ae2071bffb38f04847fc0864d730c94b9cb8ab74"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/commerceguys/addressing/zipball/ea826dbe5b3fe76960073a2167d5cf996c811cda",
- "reference": "ea826dbe5b3fe76960073a2167d5cf996c811cda",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/ae2071bffb38f04847fc0864d730c94b9cb8ab74",
+ "reference": "ae2071bffb38f04847fc0864d730c94b9cb8ab74",
"shasum": ""
},
"require": {
- "doctrine/collections": "^1.6 || ^2.0",
- "php": ">=8.0"
+ "php": ">=8.1.0",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-ctype": "^1.8",
+ "symfony/polyfill-mbstring": "^1.3"
},
"require-dev": {
- "ext-json": "*",
- "mikey179/vfsstream": "^1.6.11",
- "phpunit/phpunit": "^9.6",
- "squizlabs/php_codesniffer": "^3.7",
- "symfony/validator": "^5.4 || ^6.3 || ^7.0"
- },
- "suggest": {
- "symfony/validator": "to validate addresses"
+ "php-cs-fixer/shim": "^3.0@stable",
+ "phpstan/phpstan": "^2.0@stable",
+ "psr/container": "^1.0|^2.0",
+ "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.x-dev"
- }
- },
"autoload": {
+ "files": [
+ "src/Resources/core.php",
+ "src/Resources/debug.php",
+ "src/Resources/escaper.php",
+ "src/Resources/string_loader.php"
+ ],
"psr-4": {
- "CommerceGuys\\Addressing\\": "src"
+ "Twig\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Bojan Zivanovic"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
- "name": "Damien Tournoud"
- }
- ],
- "description": "Addressing library powered by CLDR and Google's address data.",
- "keywords": [
+ "name": "Twig Team",
+ "role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "templating"
+ ],
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/v3.27.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-05-30T17:09:26+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "bacon/bacon-qr-code",
+ "version": "v3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Bacon/BaconQrCode.git",
+ "reference": "4da2233e72eeecd9be3b62e0dc2cc9ed8e2e31c2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/4da2233e72eeecd9be3b62e0dc2cc9ed8e2e31c2",
+ "reference": "4da2233e72eeecd9be3b62e0dc2cc9ed8e2e31c2",
+ "shasum": ""
+ },
+ "require": {
+ "dasprid/enum": "^1.0.3",
+ "ext-iconv": "*",
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "phly/keep-a-changelog": "^2.12",
+ "phpunit/phpunit": "^10.5.11 || ^11.0.4",
+ "spatie/phpunit-snapshot-assertions": "^5.1.5",
+ "spatie/pixelmatch-php": "^1.2.0",
+ "squizlabs/php_codesniffer": "^3.9"
+ },
+ "suggest": {
+ "ext-imagick": "to generate QR code images"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "BaconQrCode\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-2-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Ben Scholzen 'DASPRiD'",
+ "email": "mail@dasprids.de",
+ "homepage": "https://dasprids.de/",
+ "role": "Developer"
+ }
+ ],
+ "description": "BaconQrCode is a QR code generator for PHP.",
+ "homepage": "https://github.com/Bacon/BaconQrCode",
+ "support": {
+ "issues": "https://github.com/Bacon/BaconQrCode/issues",
+ "source": "https://github.com/Bacon/BaconQrCode/tree/v3.1.1"
+ },
+ "time": "2026-04-05T21:06:35+00:00"
+ },
+ {
+ "name": "brick/math",
+ "version": "0.17.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/brick/math.git",
+ "reference": "8189e751995f9e15729c1aa2f89fa8f166ffe818"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/brick/math/zipball/8189e751995f9e15729c1aa2f89fa8f166ffe818",
+ "reference": "8189e751995f9e15729c1aa2f89fa8f166ffe818",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.2"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "2.1.22",
+ "phpunit/phpunit": "^11.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Brick\\Math\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Arbitrary-precision arithmetic library",
+ "keywords": [
+ "Arbitrary-precision",
+ "BigInteger",
+ "BigRational",
+ "arithmetic",
+ "bigdecimal",
+ "bignum",
+ "bignumber",
+ "brick",
+ "decimal",
+ "integer",
+ "math",
+ "mathematics",
+ "rational"
+ ],
+ "support": {
+ "issues": "https://github.com/brick/math/issues",
+ "source": "https://github.com/brick/math/tree/0.17.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/BenMorel",
+ "type": "github"
+ }
+ ],
+ "time": "2026-05-25T20:34:43+00:00"
+ },
+ {
+ "name": "carbonphp/carbon-doctrine-types",
+ "version": "3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git",
+ "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d",
+ "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "conflict": {
+ "doctrine/dbal": "<4.0.0 || >=5.0.0"
+ },
+ "require-dev": {
+ "doctrine/dbal": "^4.0.0",
+ "nesbot/carbon": "^2.71.0 || ^3.0.0",
+ "phpunit/phpunit": "^10.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Carbon\\Doctrine\\": "src/Carbon/Doctrine/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "KyleKatarn",
+ "email": "kylekatarnls@gmail.com"
+ }
+ ],
+ "description": "Types to use Carbon in Doctrine",
+ "keywords": [
+ "carbon",
+ "date",
+ "datetime",
+ "doctrine",
+ "time"
+ ],
+ "support": {
+ "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues",
+ "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/kylekatarnls",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/Carbon",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-02-09T16:56:22+00:00"
+ },
+ {
+ "name": "cebe/markdown",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cebe/markdown.git",
+ "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cebe/markdown/zipball/9bac5e971dd391e2802dca5400bbeacbaea9eb86",
+ "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86",
+ "shasum": ""
+ },
+ "require": {
+ "lib-pcre": "*",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "cebe/indent": "*",
+ "facebook/xhprof": "*@dev",
+ "phpunit/phpunit": "4.1.*"
+ },
+ "bin": [
+ "bin/markdown"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "cebe\\markdown\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Carsten Brandt",
+ "email": "mail@cebe.cc",
+ "homepage": "http://cebe.cc/",
+ "role": "Creator"
+ }
+ ],
+ "description": "A super fast, highly extensible markdown parser for PHP",
+ "homepage": "https://github.com/cebe/markdown#readme",
+ "keywords": [
+ "extensible",
+ "fast",
+ "gfm",
+ "markdown",
+ "markdown-extra"
+ ],
+ "support": {
+ "issues": "https://github.com/cebe/markdown/issues",
+ "source": "https://github.com/cebe/markdown"
+ },
+ "time": "2018-03-26T11:24:36+00:00"
+ },
+ {
+ "name": "commerceguys/addressing",
+ "version": "v2.2.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/commerceguys/addressing.git",
+ "reference": "15b789e5e6ededaf803d23c56cdc300a94522a7c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/commerceguys/addressing/zipball/15b789e5e6ededaf803d23c56cdc300a94522a7c",
+ "reference": "15b789e5e6ededaf803d23c56cdc300a94522a7c",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/collections": "^1.6 || ^2.0",
+ "php": ">=8.0"
+ },
+ "require-dev": {
+ "ext-json": "*",
+ "mikey179/vfsstream": "^1.6.11",
+ "phpunit/phpunit": "^9.6",
+ "squizlabs/php_codesniffer": "^3.7",
+ "symfony/validator": "^5.4 || ^6.3 || ^7.0 || ^8.0"
+ },
+ "suggest": {
+ "symfony/validator": "to validate addresses"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "CommerceGuys\\Addressing\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bojan Zivanovic"
+ },
+ {
+ "name": "Damien Tournoud"
+ }
+ ],
+ "description": "Addressing library powered by CLDR and Google's address data.",
+ "keywords": [
"address",
"internationalization",
"localization",
"postal"
],
"support": {
- "issues": "https://github.com/commerceguys/addressing/issues",
- "source": "https://github.com/commerceguys/addressing/tree/v2.2.4"
+ "issues": "https://github.com/commerceguys/addressing/issues",
+ "source": "https://github.com/commerceguys/addressing/tree/v2.2.5"
+ },
+ "time": "2026-01-05T13:00:32+00:00"
+ },
+ {
+ "name": "composer/pcre",
+ "version": "3.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/pcre.git",
+ "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
+ "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan": "<1.11.10"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.12 || ^2",
+ "phpstan/phpstan-strict-rules": "^1 || ^2",
+ "phpunit/phpunit": "^8 || ^9"
+ },
+ "type": "library",
+ "extra": {
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ },
+ "branch-alias": {
+ "dev-main": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Pcre\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "PCRE wrapping library that offers type-safe preg_* replacements.",
+ "keywords": [
+ "PCRE",
+ "preg",
+ "regex",
+ "regular expression"
+ ],
+ "support": {
+ "issues": "https://github.com/composer/pcre/issues",
+ "source": "https://github.com/composer/pcre/tree/3.3.2"
+ },
+ "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-11-12T16:29:46+00:00"
+ },
+ {
+ "name": "composer/semver",
+ "version": "3.4.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/semver.git",
+ "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95",
+ "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95",
+ "shasum": ""
+ },
+ "require": {
+ "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-main": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Semver\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ },
+ {
+ "name": "Rob Bast",
+ "email": "rob.bast@gmail.com",
+ "homepage": "http://robbast.nl"
+ }
+ ],
+ "description": "Semver library that offers utilities, version constraint parsing and validation.",
+ "keywords": [
+ "semantic",
+ "semver",
+ "validation",
+ "versioning"
+ ],
+ "support": {
+ "irc": "ircs://irc.libera.chat:6697/composer",
+ "issues": "https://github.com/composer/semver/issues",
+ "source": "https://github.com/composer/semver/tree/3.4.4"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ }
+ ],
+ "time": "2025-08-20T19:15:30+00:00"
+ },
+ {
+ "name": "craftcms/cms",
+ "version": "5.10.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/craftcms/cms.git",
+ "reference": "dc39613556a054f7674a3bdccdb813b8b7e28b34"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/craftcms/cms/zipball/dc39613556a054f7674a3bdccdb813b8b7e28b34",
+ "reference": "dc39613556a054f7674a3bdccdb813b8b7e28b34",
+ "shasum": ""
+ },
+ "require": {
+ "bacon/bacon-qr-code": "^3.0",
+ "commerceguys/addressing": "^2.1.1",
+ "composer/semver": "^3.3.2",
+ "craftcms/plugin-installer": "~1.6.0",
+ "craftcms/server-check": "~5.1.0",
+ "craftcms/url-validator": "^1.0",
+ "creocoder/yii2-nested-sets": "~0.9.0",
+ "elvanto/litemoji": "~4.3.0",
+ "enshrined/svg-sanitize": "~0.22.0",
+ "ext-bcmath": "*",
+ "ext-curl": "*",
+ "ext-dom": "*",
+ "ext-intl": "*",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
+ "ext-pcre": "*",
+ "ext-pdo": "*",
+ "ext-zip": "*",
+ "guzzlehttp/guzzle": "^7.2.0",
+ "illuminate/collections": "^v10.42.0",
+ "illuminate/support": "^10.49",
+ "league/uri": "^7.0",
+ "mikehaertl/php-shellcommand": "^1.6.3",
+ "moneyphp/money": "^4.0",
+ "monolog/monolog": "^3.0",
+ "php": "^8.2",
+ "phpdocumentor/reflection-docblock": "^5.3",
+ "phpoffice/phpspreadsheet": "^5.3",
+ "pixelandtonic/graphql-php": "~14.11.10.1",
+ "pixelandtonic/imagine": "~1.5.2.1",
+ "pragmarx/google2fa": "^8.0",
+ "pragmarx/recovery": "^0.2.1",
+ "samdark/yii2-psr-log-target": "^1.1.3",
+ "seld/cli-prompt": "^1.0.4",
+ "symfony/css-selector": "^6.0|^7.0",
+ "symfony/dom-crawler": "^6.0|^7.0",
+ "symfony/filesystem": "^6.3",
+ "symfony/http-client": "^6.0.3|^7.0",
+ "symfony/property-access": "^7.0",
+ "symfony/property-info": "^7.0",
+ "symfony/serializer": "^6.4|^7.0",
+ "symfony/var-dumper": "^5.0|^6.0|^7.0",
+ "symfony/yaml": "^5.2.3|^6.0|^7.0",
+ "theiconic/name-parser": "^1.2",
+ "twig/twig": "~3.27.0",
+ "voku/portable-ascii": "^2.0",
+ "web-auth/webauthn-lib": "~5.2.4",
+ "yiisoft/yii2": "~2.0.55.0",
+ "yiisoft/yii2-debug": "~2.1.27.0",
+ "yiisoft/yii2-queue": "~2.3.2",
+ "yiisoft/yii2-symfonymailer": "^4.0.0"
+ },
+ "provide": {
+ "bower-asset/inputmask": "5.0.9",
+ "bower-asset/jquery": "3.6.1",
+ "bower-asset/punycode": "^2.2",
+ "bower-asset/yii2-pjax": "~2.0.1",
+ "yii2tech/ar-softdelete": "1.0.4"
+ },
+ "require-dev": {
+ "codeception/codeception": "^5.2.0",
+ "codeception/lib-innerbrowser": "4.0.1",
+ "codeception/module-asserts": "^3.0.0",
+ "codeception/module-datafactory": "^3.0.0",
+ "codeception/module-phpbrowser": "^3.0.0",
+ "codeception/module-rest": "^3.3.2",
+ "codeception/module-yii2": "^1.1.9",
+ "craftcms/ecs": "dev-main",
+ "fakerphp/faker": "^1.19.0",
+ "league/factory-muffin": "^3.3.0",
+ "phpstan/phpstan": "^2.1",
+ "rector/rector": "^2.0",
+ "vlucas/phpdotenv": "^5.4.1",
+ "yiisoft/yii2-redis": "^2.0"
+ },
+ "suggest": {
+ "ext-exif": "Adds support for parsing image EXIF data.",
+ "ext-iconv": "Adds support for more character encodings than PHP’s built-in mb_convert_encoding() function, which Craft will take advantage of when converting strings to UTF-8.",
+ "ext-imagick": "Adds support for more image processing formats and options."
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "craft\\": "src/",
+ "yii2tech\\ar\\softdelete\\": "lib/ar-softdelete/src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "proprietary"
+ ],
+ "authors": [
+ {
+ "name": "Pixel & Tonic",
+ "homepage": "https://pixelandtonic.com/"
+ }
+ ],
+ "description": "Craft CMS",
+ "homepage": "https://craftcms.com",
+ "keywords": [
+ "cms",
+ "craftcms",
+ "yii2"
+ ],
+ "support": {
+ "docs": "https://craftcms.com/docs/5.x/",
+ "email": "support@craftcms.com",
+ "forum": "https://craftcms.stackexchange.com/",
+ "issues": "https://github.com/craftcms/cms/issues?state=open",
+ "rss": "https://github.com/craftcms/cms/releases.atom",
+ "source": "https://github.com/craftcms/cms"
+ },
+ "time": "2026-06-23T15:45:02+00:00"
+ },
+ {
+ "name": "craftcms/plugin-installer",
+ "version": "1.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/craftcms/plugin-installer.git",
+ "reference": "bd1650e8da6d5ca7a8527068d3e51c34bc7b6b4f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/craftcms/plugin-installer/zipball/bd1650e8da6d5ca7a8527068d3e51c34bc7b6b4f",
+ "reference": "bd1650e8da6d5ca7a8527068d3e51c34bc7b6b4f",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0 || ^2.0",
+ "php": ">=5.4"
+ },
+ "require-dev": {
+ "composer/composer": "^1.0 || ^2.0"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "craft\\composer\\Plugin"
+ },
+ "autoload": {
+ "psr-4": {
+ "craft\\composer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Craft CMS Plugin Installer",
+ "homepage": "https://craftcms.com/",
+ "keywords": [
+ "cms",
+ "composer",
+ "craftcms",
+ "installer",
+ "plugin"
+ ],
+ "support": {
+ "docs": "https://craftcms.com/docs",
+ "email": "support@craftcms.com",
+ "forum": "https://craftcms.stackexchange.com/",
+ "issues": "https://github.com/craftcms/cms/issues?state=open",
+ "rss": "https://craftcms.com/changelog.rss",
+ "source": "https://github.com/craftcms/cms"
+ },
+ "time": "2023-02-22T13:17:00+00:00"
+ },
+ {
+ "name": "craftcms/server-check",
+ "version": "5.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/craftcms/server-check.git",
+ "reference": "7a4f1720c4fe1f0731254a82e63060a217f51cdc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/craftcms/server-check/zipball/7a4f1720c4fe1f0731254a82e63060a217f51cdc",
+ "reference": "7a4f1720c4fe1f0731254a82e63060a217f51cdc",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "server/requirements"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Craft CMS Server Check",
+ "homepage": "https://craftcms.com/",
+ "keywords": [
+ "cms",
+ "craftcms",
+ "requirements",
+ "yii2"
+ ],
+ "support": {
+ "docs": "https://github.com/craftcms/docs",
+ "email": "support@craftcms.com",
+ "forum": "https://craftcms.stackexchange.com/",
+ "issues": "https://github.com/craftcms/server-check/issues?state=open",
+ "rss": "https://github.com/craftcms/server-check/releases.atom",
+ "source": "https://github.com/craftcms/server-check"
+ },
+ "time": "2026-04-07T16:48:35+00:00"
+ },
+ {
+ "name": "craftcms/url-validator",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/craftcms/url-validator.git",
+ "reference": "75b44bc4d3f89feb9410b85d385f01210edd5eb1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/craftcms/url-validator/zipball/75b44bc4d3f89feb9410b85d385f01210edd5eb1",
+ "reference": "75b44bc4d3f89feb9410b85d385f01210edd5eb1",
+ "shasum": ""
+ },
+ "require": {
+ "ext-filter": "*",
+ "php": "^8.0.2"
+ },
+ "require-dev": {
+ "laravel/pint": "^1.29",
+ "nunomaduro/collision": "^8.1",
+ "pestphp/pest": "^3.0",
+ "phpstan/phpstan": "^2.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "CraftCms\\UrlValidator\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Pixel & Tonic",
+ "homepage": "https://pixelandtonic.com/"
+ }
+ ],
+ "description": "Validate URLs and IP addresses against SSRF, DNS rebinding, and cloud-metadata attacks.",
+ "homepage": "https://github.com/craftcms/url-validator",
+ "keywords": [
+ "IP",
+ "craftcms",
+ "security",
+ "ssrf",
+ "url",
+ "validation"
+ ],
+ "support": {
+ "issues": "https://github.com/craftcms/url-validator/issues",
+ "source": "https://github.com/craftcms/url-validator/tree/1.0.0"
+ },
+ "time": "2026-06-15T17:29:09+00:00"
+ },
+ {
+ "name": "creocoder/yii2-nested-sets",
+ "version": "0.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/creocoder/yii2-nested-sets.git",
+ "reference": "cb8635a459b6246e5a144f096b992dcc30cf9954"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/creocoder/yii2-nested-sets/zipball/cb8635a459b6246e5a144f096b992dcc30cf9954",
+ "reference": "cb8635a459b6246e5a144f096b992dcc30cf9954",
+ "shasum": ""
+ },
+ "require": {
+ "yiisoft/yii2": "*"
+ },
+ "type": "yii2-extension",
+ "autoload": {
+ "psr-4": {
+ "creocoder\\nestedsets\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Alexander Kochetov",
+ "email": "creocoder@gmail.com"
+ }
+ ],
+ "description": "The nested sets behavior for the Yii framework",
+ "keywords": [
+ "nested sets",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/creocoder/yii2-nested-sets/issues",
+ "source": "https://github.com/creocoder/yii2-nested-sets/tree/master"
+ },
+ "time": "2015-01-27T10:53:51+00:00"
+ },
+ {
+ "name": "dasprid/enum",
+ "version": "1.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/DASPRiD/Enum.git",
+ "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce",
+ "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1 <9.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11",
+ "squizlabs/php_codesniffer": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DASPRiD\\Enum\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-2-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Ben Scholzen 'DASPRiD'",
+ "email": "mail@dasprids.de",
+ "homepage": "https://dasprids.de/",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP 7.1 enum implementation",
+ "keywords": [
+ "enum",
+ "map"
+ ],
+ "support": {
+ "issues": "https://github.com/DASPRiD/Enum/issues",
+ "source": "https://github.com/DASPRiD/Enum/tree/1.0.7"
+ },
+ "time": "2025-09-16T12:23:56+00:00"
+ },
+ {
+ "name": "doctrine/collections",
+ "version": "2.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/collections.git",
+ "reference": "7713da39d8e237f28411d6a616a3dce5e20d5de2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/collections/zipball/7713da39d8e237f28411d6a616a3dce5e20d5de2",
+ "reference": "7713da39d8e237f28411d6a616a3dce5e20d5de2",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/deprecations": "^1",
+ "php": "^8.1",
+ "symfony/polyfill-php84": "^1.30"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^14",
+ "ext-json": "*",
+ "phpstan/phpstan": "^2.1.30",
+ "phpstan/phpstan-phpunit": "^2.0.7",
+ "phpunit/phpunit": "^10.5.58 || ^11.5.42 || ^12.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\Collections\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.",
+ "homepage": "https://www.doctrine-project.org/projects/collections.html",
+ "keywords": [
+ "array",
+ "collections",
+ "iterators",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/collections/issues",
+ "source": "https://github.com/doctrine/collections/tree/2.6.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcollections",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-01-15T10:01:58+00:00"
+ },
+ {
+ "name": "doctrine/deprecations",
+ "version": "1.1.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca",
+ "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<=7.5 || >=14"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9 || ^12 || ^14",
+ "phpstan/phpstan": "1.4.10 || 2.1.30",
+ "phpstan/phpstan-phpunit": "^1.0 || ^2",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0",
+ "psr/log": "^1 || ^2 || ^3"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "support": {
+ "issues": "https://github.com/doctrine/deprecations/issues",
+ "source": "https://github.com/doctrine/deprecations/tree/1.1.6"
+ },
+ "time": "2026-02-07T07:09:04+00:00"
+ },
+ {
+ "name": "doctrine/inflector",
+ "version": "2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/inflector.git",
+ "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b",
+ "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^12.0 || ^13.0",
+ "phpstan/phpstan": "^1.12 || ^2.0",
+ "phpstan/phpstan-phpunit": "^1.4 || ^2.0",
+ "phpstan/phpstan-strict-rules": "^1.6 || ^2.0",
+ "phpunit/phpunit": "^8.5 || ^12.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Inflector\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.",
+ "homepage": "https://www.doctrine-project.org/projects/inflector.html",
+ "keywords": [
+ "inflection",
+ "inflector",
+ "lowercase",
+ "manipulation",
+ "php",
+ "plural",
+ "singular",
+ "strings",
+ "uppercase",
+ "words"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/inflector/issues",
+ "source": "https://github.com/doctrine/inflector/tree/2.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2025-08-10T19:31:58+00:00"
+ },
+ {
+ "name": "doctrine/lexer",
+ "version": "3.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/lexer.git",
+ "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
+ "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^12",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^10.5",
+ "psalm/plugin-phpunit": "^0.18.3",
+ "vimeo/psalm": "^5.21"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\Lexer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
+ "homepage": "https://www.doctrine-project.org/projects/lexer.html",
+ "keywords": [
+ "annotations",
+ "docblock",
+ "lexer",
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/lexer/issues",
+ "source": "https://github.com/doctrine/lexer/tree/3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-02-05T11:56:58+00:00"
+ },
+ {
+ "name": "egulias/email-validator",
+ "version": "4.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/egulias/EmailValidator.git",
+ "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa",
+ "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/lexer": "^2.0 || ^3.0",
+ "php": ">=8.1",
+ "symfony/polyfill-intl-idn": "^1.26"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.2",
+ "vimeo/psalm": "^5.12"
+ },
+ "suggest": {
+ "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Egulias\\EmailValidator\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Eduardo Gulias Davis"
+ }
+ ],
+ "description": "A library for validating emails against several RFCs",
+ "homepage": "https://github.com/egulias/EmailValidator",
+ "keywords": [
+ "email",
+ "emailvalidation",
+ "emailvalidator",
+ "validation",
+ "validator"
+ ],
+ "support": {
+ "issues": "https://github.com/egulias/EmailValidator/issues",
+ "source": "https://github.com/egulias/EmailValidator/tree/4.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/egulias",
+ "type": "github"
+ }
+ ],
+ "time": "2025-03-06T22:45:56+00:00"
+ },
+ {
+ "name": "elvanto/litemoji",
+ "version": "4.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/elvanto/litemoji.git",
+ "reference": "f13cf10686f7110a3b17d09de03050d0708840b8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/elvanto/litemoji/zipball/f13cf10686f7110a3b17d09de03050d0708840b8",
+ "reference": "f13cf10686f7110a3b17d09de03050d0708840b8",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "milesj/emojibase": "7.0.*",
+ "phpunit/phpunit": "^9.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "LitEmoji\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A PHP library simplifying the conversion of unicode, HTML and shortcode emoji.",
+ "keywords": [
+ "emoji",
+ "php-emoji"
+ ],
+ "support": {
+ "issues": "https://github.com/elvanto/litemoji/issues",
+ "source": "https://github.com/elvanto/litemoji/tree/4.3.0"
+ },
+ "time": "2022-10-28T02:32:19+00:00"
+ },
+ {
+ "name": "enshrined/svg-sanitize",
+ "version": "0.22.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/darylldoyle/svg-sanitizer.git",
+ "reference": "0afa95ea74be155a7bcd6c6fb60c276c39984500"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/darylldoyle/svg-sanitizer/zipball/0afa95ea74be155a7bcd6c6fb60c276c39984500",
+ "reference": "0afa95ea74be155a7bcd6c6fb60c276c39984500",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.5 || ^8.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "enshrined\\svgSanitize\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "GPL-2.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Daryll Doyle",
+ "email": "daryll@enshrined.co.uk"
+ }
+ ],
+ "description": "An SVG sanitizer for PHP",
+ "support": {
+ "issues": "https://github.com/darylldoyle/svg-sanitizer/issues",
+ "source": "https://github.com/darylldoyle/svg-sanitizer/tree/0.22.0"
+ },
+ "time": "2025-08-12T10:13:48+00:00"
+ },
+ {
+ "name": "ezyang/htmlpurifier",
+ "version": "v4.19.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ezyang/htmlpurifier.git",
+ "reference": "b287d2a16aceffbf6e0295559b39662612b77fcf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/b287d2a16aceffbf6e0295559b39662612b77fcf",
+ "reference": "b287d2a16aceffbf6e0295559b39662612b77fcf",
+ "shasum": ""
+ },
+ "require": {
+ "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
+ },
+ "require-dev": {
+ "cerdic/css-tidy": "^1.7 || ^2.0",
+ "simpletest/simpletest": "dev-master"
+ },
+ "suggest": {
+ "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
+ "ext-bcmath": "Used for unit conversion and imagecrash protection",
+ "ext-iconv": "Converts text to and from non-UTF-8 encodings",
+ "ext-tidy": "Used for pretty-printing HTML"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "library/HTMLPurifier.composer.php"
+ ],
+ "psr-0": {
+ "HTMLPurifier": "library/"
+ },
+ "exclude-from-classmap": [
+ "/library/HTMLPurifier/Language/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Edward Z. Yang",
+ "email": "admin@htmlpurifier.org",
+ "homepage": "http://ezyang.com"
+ }
+ ],
+ "description": "Standards compliant HTML filter written in PHP",
+ "homepage": "http://htmlpurifier.org/",
+ "keywords": [
+ "html"
+ ],
+ "support": {
+ "issues": "https://github.com/ezyang/htmlpurifier/issues",
+ "source": "https://github.com/ezyang/htmlpurifier/tree/v4.19.0"
+ },
+ "time": "2025-10-17T16:34:55+00:00"
+ },
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "7.13.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "55901a76dfd2006a0cc012b9e3c5b487f796478d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/55901a76dfd2006a0cc012b9e3c5b487f796478d",
+ "reference": "55901a76dfd2006a0cc012b9e3c5b487f796478d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "guzzlehttp/promises": "^2.5",
+ "guzzlehttp/psr7": "^2.12.3",
+ "php": "^7.2.5 || ^8.0",
+ "psr/http-client": "^1.0",
+ "symfony/deprecation-contracts": "^2.5 || ^3.0",
+ "symfony/polyfill-php80": "^1.25"
+ },
+ "provide": {
+ "psr/http-client-implementation": "1.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "ext-curl": "*",
+ "guzzle/client-integration-tests": "3.0.2",
+ "guzzlehttp/test-server": "^0.6",
+ "php-http/message-factory": "^1.1",
+ "phpunit/phpunit": "^8.5.52 || ^9.6.34",
+ "psr/log": "^1.1 || ^2.0 || ^3.0"
+ },
+ "suggest": {
+ "ext-curl": "Required for CURL handler support",
+ "ext-intl": "Required for Internationalized Domain Name (IDN) support",
+ "psr/log": "Required for using the Log middleware"
+ },
+ "type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": false
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Jeremy Lindblom",
+ "email": "jeremeamia@gmail.com",
+ "homepage": "https://github.com/jeremeamia"
+ },
+ {
+ "name": "George Mponos",
+ "email": "gmponos@gmail.com",
+ "homepage": "https://github.com/gmponos"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://github.com/sagikazarmark"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "psr-18",
+ "psr-7",
+ "rest",
+ "web service"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/guzzle/issues",
+ "source": "https://github.com/guzzle/guzzle/tree/7.13.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-06-29T20:14:18+00:00"
+ },
+ {
+ "name": "guzzlehttp/promises",
+ "version": "2.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "4360e982f87f5f258bf872d094647791db2f4c8e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/4360e982f87f5f258bf872d094647791db2f4c8e",
+ "reference": "4360e982f87f5f258bf872d094647791db2f4c8e",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2.5 || ^8.0",
+ "symfony/deprecation-contracts": "^2.5 || ^3.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "phpunit/phpunit": "^8.5.52 || ^9.6.34"
+ },
+ "type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": false
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Promise\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "Guzzle promises library",
+ "keywords": [
+ "promise"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/promises/issues",
+ "source": "https://github.com/guzzle/promises/tree/2.5.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-06-02T12:23:43+00:00"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "2.12.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "7ec62dc3f44aa218487dbed81a9bf9bc647be55d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/7ec62dc3f44aa218487dbed81a9bf9bc647be55d",
+ "reference": "7ec62dc3f44aa218487dbed81a9bf9bc647be55d",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2.5 || ^8.0",
+ "psr/http-factory": "^1.0",
+ "psr/http-message": "^1.1 || ^2.0",
+ "ralouphie/getallheaders": "^3.0",
+ "symfony/deprecation-contracts": "^2.5 || ^3.0",
+ "symfony/polyfill-php80": "^1.25"
+ },
+ "provide": {
+ "psr/http-factory-implementation": "1.0",
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "http-interop/http-factory-tests": "1.1.0",
+ "jshttp/mime-db": "1.54.0.1",
+ "phpunit/phpunit": "^8.5.52 || ^9.6.34"
+ },
+ "suggest": {
+ "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
+ },
+ "type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": false
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "George Mponos",
+ "email": "gmponos@gmail.com",
+ "homepage": "https://github.com/gmponos"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://github.com/sagikazarmark"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://sagikazarmark.hu"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "psr-7",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/psr7/issues",
+ "source": "https://github.com/guzzle/psr7/tree/2.12.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-06-23T15:21:08+00:00"
+ },
+ {
+ "name": "illuminate/collections",
+ "version": "v10.49.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/collections.git",
+ "reference": "6ae9c74fa92d4e1824d1b346cd435e8eacdc3232"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/collections/zipball/6ae9c74fa92d4e1824d1b346cd435e8eacdc3232",
+ "reference": "6ae9c74fa92d4e1824d1b346cd435e8eacdc3232",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/conditionable": "^10.0",
+ "illuminate/contracts": "^10.0",
+ "illuminate/macroable": "^10.0",
+ "php": "^8.1"
+ },
+ "suggest": {
+ "symfony/var-dumper": "Required to use the dump method (^6.2)."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "10.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "helpers.php"
+ ],
+ "psr-4": {
+ "Illuminate\\Support\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "The Illuminate Collections package.",
+ "homepage": "https://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "time": "2025-09-08T19:05:53+00:00"
+ },
+ {
+ "name": "illuminate/conditionable",
+ "version": "v10.49.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/conditionable.git",
+ "reference": "47c700320b7a419f0d188d111f3bbed978fcbd3f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/conditionable/zipball/47c700320b7a419f0d188d111f3bbed978fcbd3f",
+ "reference": "47c700320b7a419f0d188d111f3bbed978fcbd3f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.0.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "10.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Support\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "The Illuminate Conditionable package.",
+ "homepage": "https://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "time": "2025-03-24T11:47:24+00:00"
+ },
+ {
+ "name": "illuminate/contracts",
+ "version": "v10.49.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/contracts.git",
+ "reference": "2393ef579e020d88e24283913c815c3e2c143323"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/contracts/zipball/2393ef579e020d88e24283913c815c3e2c143323",
+ "reference": "2393ef579e020d88e24283913c815c3e2c143323",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1",
+ "psr/container": "^1.1.1|^2.0.1",
+ "psr/simple-cache": "^1.0|^2.0|^3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "10.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Contracts\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "The Illuminate Contracts package.",
+ "homepage": "https://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
},
- "time": "2025-01-13T16:03:24+00:00"
+ "time": "2025-03-24T11:47:24+00:00"
},
{
- "name": "composer/semver",
- "version": "3.4.4",
+ "name": "illuminate/macroable",
+ "version": "v10.49.0",
"source": {
"type": "git",
- "url": "https://github.com/composer/semver.git",
- "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95"
+ "url": "https://github.com/illuminate/macroable.git",
+ "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95",
- "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95",
+ "url": "https://api.github.com/repos/illuminate/macroable/zipball/dff667a46ac37b634dcf68909d9d41e94dc97c27",
+ "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27",
"shasum": ""
},
"require": {
- "php": "^5.3.2 || ^7.0 || ^8.0"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.11",
- "symfony/phpunit-bridge": "^3 || ^7"
+ "php": "^8.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "3.x-dev"
+ "dev-master": "10.x-dev"
}
},
"autoload": {
"psr-4": {
- "Composer\\Semver\\": "src"
+ "Illuminate\\Support\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -341,391 +2253,497 @@
],
"authors": [
{
- "name": "Nils Adermann",
- "email": "naderman@naderman.de",
- "homepage": "http://www.naderman.de"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- },
- {
- "name": "Rob Bast",
- "email": "rob.bast@gmail.com",
- "homepage": "http://robbast.nl"
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
}
],
- "description": "Semver library that offers utilities, version constraint parsing and validation.",
- "keywords": [
- "semantic",
- "semver",
- "validation",
- "versioning"
- ],
+ "description": "The Illuminate Macroable package.",
+ "homepage": "https://laravel.com",
"support": {
- "irc": "ircs://irc.libera.chat:6697/composer",
- "issues": "https://github.com/composer/semver/issues",
- "source": "https://github.com/composer/semver/tree/3.4.4"
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
},
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
+ "time": "2023-06-05T12:46:42+00:00"
+ },
+ {
+ "name": "illuminate/support",
+ "version": "v10.49.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/illuminate/support.git",
+ "reference": "28b505e671dbe119e4e32a75c78f87189d046e39"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/illuminate/support/zipball/28b505e671dbe119e4e32a75c78f87189d046e39",
+ "reference": "28b505e671dbe119e4e32a75c78f87189d046e39",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/inflector": "^2.0",
+ "ext-ctype": "*",
+ "ext-filter": "*",
+ "ext-mbstring": "*",
+ "illuminate/collections": "^10.0",
+ "illuminate/conditionable": "^10.0",
+ "illuminate/contracts": "^10.0",
+ "illuminate/macroable": "^10.0",
+ "nesbot/carbon": "^2.67",
+ "php": "^8.1",
+ "voku/portable-ascii": "^2.0"
+ },
+ "conflict": {
+ "tightenco/collect": "<5.5.33"
+ },
+ "suggest": {
+ "illuminate/filesystem": "Required to use the composer class (^10.0).",
+ "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.6).",
+ "ramsey/uuid": "Required to use Str::uuid() (^4.7).",
+ "symfony/process": "Required to use the composer class (^6.2).",
+ "symfony/uid": "Required to use Str::ulid() (^6.2).",
+ "symfony/var-dumper": "Required to use the dd function (^6.2).",
+ "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "10.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "helpers.php"
+ ],
+ "psr-4": {
+ "Illuminate\\Support\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
{
- "url": "https://github.com/composer",
- "type": "github"
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
}
],
- "time": "2025-08-20T19:15:30+00:00"
+ "description": "The Illuminate Support package.",
+ "homepage": "https://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "time": "2025-09-08T19:05:53+00:00"
},
{
- "name": "craftcms/cms",
- "version": "5.8.19",
+ "name": "laravel/pint",
+ "version": "v1.25.1",
"source": {
"type": "git",
- "url": "https://github.com/craftcms/cms.git",
- "reference": "2fdb2031cdf41875121c3f4b0094551ae95a2c38"
+ "url": "https://github.com/laravel/pint.git",
+ "reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/craftcms/cms/zipball/2fdb2031cdf41875121c3f4b0094551ae95a2c38",
- "reference": "2fdb2031cdf41875121c3f4b0094551ae95a2c38",
+ "url": "https://api.github.com/repos/laravel/pint/zipball/5016e263f95d97670d71b9a987bd8996ade6d8d9",
+ "reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9",
"shasum": ""
},
"require": {
- "bacon/bacon-qr-code": "^2.0",
- "commerceguys/addressing": "^2.1.1",
- "composer/semver": "^3.3.2",
- "craftcms/plugin-installer": "~1.6.0",
- "craftcms/server-check": "~5.0.1",
- "creocoder/yii2-nested-sets": "~0.9.0",
- "elvanto/litemoji": "~4.3.0",
- "enshrined/svg-sanitize": "~0.22.0",
- "ext-bcmath": "*",
- "ext-curl": "*",
- "ext-dom": "*",
- "ext-intl": "*",
"ext-json": "*",
"ext-mbstring": "*",
- "ext-openssl": "*",
- "ext-pcre": "*",
- "ext-pdo": "*",
- "ext-zip": "*",
- "guzzlehttp/guzzle": "^7.2.0",
- "illuminate/collections": "^v10.42.0",
- "league/uri": "^7.0",
- "mikehaertl/php-shellcommand": "^1.6.3",
- "moneyphp/money": "^4.0",
- "monolog/monolog": "^3.0",
- "php": "^8.2",
- "phpdocumentor/reflection-docblock": "^5.3",
- "pixelandtonic/imagine": "~1.3.3.1",
- "pragmarx/google2fa": "^8.0",
- "pragmarx/recovery": "^0.2.1",
- "samdark/yii2-psr-log-target": "^1.1.3",
- "seld/cli-prompt": "^1.0.4",
- "symfony/css-selector": "^6.0|^7.0",
- "symfony/dom-crawler": "^6.0|^7.0",
- "symfony/filesystem": "^6.3",
- "symfony/http-client": "^6.0.3|^7.0",
- "symfony/property-access": "^7.0",
- "symfony/property-info": "^7.0",
- "symfony/serializer": "^6.4",
- "symfony/var-dumper": "^5.0|^6.0|^7.0",
- "symfony/yaml": "^5.2.3|^6.0|^7.0",
- "theiconic/name-parser": "^1.2",
- "twig/twig": "~3.15.0",
- "voku/stringy": "^6.4.0",
- "web-auth/webauthn-lib": "~4.9.0",
- "webonyx/graphql-php": "~14.11.10",
- "yiisoft/yii2": "~2.0.52.0",
- "yiisoft/yii2-debug": "~2.1.27.0",
- "yiisoft/yii2-queue": "~2.3.2",
- "yiisoft/yii2-symfonymailer": "^4.0.0"
- },
- "provide": {
- "bower-asset/inputmask": "5.0.9",
- "bower-asset/jquery": "3.6.1",
- "bower-asset/punycode": "^1.4",
- "bower-asset/yii2-pjax": "~2.0.1",
- "yii2tech/ar-softdelete": "1.0.4"
+ "ext-tokenizer": "*",
+ "ext-xml": "*",
+ "php": "^8.2.0"
},
"require-dev": {
- "codeception/codeception": "^5.2.0",
- "codeception/lib-innerbrowser": "4.0.1",
- "codeception/module-asserts": "^3.0.0",
- "codeception/module-datafactory": "^3.0.0",
- "codeception/module-phpbrowser": "^3.0.0",
- "codeception/module-rest": "^3.3.2",
- "codeception/module-yii2": "^1.1.9",
- "craftcms/ecs": "dev-main",
- "fakerphp/faker": "^1.19.0",
- "league/factory-muffin": "^3.3.0",
- "phpstan/phpstan": "^2.1",
- "rector/rector": "^2.0",
- "vlucas/phpdotenv": "^5.4.1",
- "yiisoft/yii2-redis": "^2.0"
- },
- "suggest": {
- "ext-exif": "Adds support for parsing image EXIF data.",
- "ext-iconv": "Adds support for more character encodings than PHP’s built-in mb_convert_encoding() function, which Craft will take advantage of when converting strings to UTF-8.",
- "ext-imagick": "Adds support for more image processing formats and options."
+ "friendsofphp/php-cs-fixer": "^3.87.2",
+ "illuminate/view": "^11.46.0",
+ "larastan/larastan": "^3.7.1",
+ "laravel-zero/framework": "^11.45.0",
+ "mockery/mockery": "^1.6.12",
+ "nunomaduro/termwind": "^2.3.1",
+ "pestphp/pest": "^2.36.0"
},
- "type": "library",
+ "bin": [
+ "builds/pint"
+ ],
+ "type": "project",
"autoload": {
"psr-4": {
- "craft\\": "src/",
- "yii2tech\\ar\\softdelete\\": "lib/ar-softdelete/src/"
+ "App\\": "app/",
+ "Database\\Seeders\\": "database/seeders/",
+ "Database\\Factories\\": "database/factories/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "proprietary"
+ "MIT"
],
"authors": [
{
- "name": "Pixel & Tonic",
- "homepage": "https://pixelandtonic.com/"
+ "name": "Nuno Maduro",
+ "email": "enunomaduro@gmail.com"
}
],
- "description": "Craft CMS",
- "homepage": "https://craftcms.com",
+ "description": "An opinionated code formatter for PHP.",
+ "homepage": "https://laravel.com",
"keywords": [
- "cms",
- "craftcms",
- "yii2"
+ "format",
+ "formatter",
+ "lint",
+ "linter",
+ "php"
],
"support": {
- "docs": "https://craftcms.com/docs/5.x/",
- "email": "support@craftcms.com",
- "forum": "https://craftcms.stackexchange.com/",
- "issues": "https://github.com/craftcms/cms/issues?state=open",
- "rss": "https://github.com/craftcms/cms/releases.atom",
- "source": "https://github.com/craftcms/cms"
+ "issues": "https://github.com/laravel/pint/issues",
+ "source": "https://github.com/laravel/pint"
},
- "time": "2025-10-28T19:21:54+00:00"
+ "time": "2025-09-19T02:57:12+00:00"
},
{
- "name": "craftcms/plugin-installer",
- "version": "1.6.0",
+ "name": "league/uri",
+ "version": "7.8.1",
"source": {
"type": "git",
- "url": "https://github.com/craftcms/plugin-installer.git",
- "reference": "bd1650e8da6d5ca7a8527068d3e51c34bc7b6b4f"
+ "url": "https://github.com/thephpleague/uri.git",
+ "reference": "08cf38e3924d4f56238125547b5720496fac8fd4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/craftcms/plugin-installer/zipball/bd1650e8da6d5ca7a8527068d3e51c34bc7b6b4f",
- "reference": "bd1650e8da6d5ca7a8527068d3e51c34bc7b6b4f",
+ "url": "https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4",
+ "reference": "08cf38e3924d4f56238125547b5720496fac8fd4",
"shasum": ""
},
"require": {
- "composer-plugin-api": "^1.0 || ^2.0",
- "php": ">=5.4"
+ "league/uri-interfaces": "^7.8.1",
+ "php": "^8.1",
+ "psr/http-factory": "^1"
},
- "require-dev": {
- "composer/composer": "^1.0 || ^2.0"
+ "conflict": {
+ "league/uri-schemes": "^1.0"
},
- "type": "composer-plugin",
+ "suggest": {
+ "ext-bcmath": "to improve IPV4 host parsing",
+ "ext-dom": "to convert the URI into an HTML anchor tag",
+ "ext-fileinfo": "to create Data URI from file contennts",
+ "ext-gmp": "to improve IPV4 host parsing",
+ "ext-intl": "to handle IDN host with the best performance",
+ "ext-uri": "to use the PHP native URI class",
+ "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain",
+ "league/uri-components": "to provide additional tools to manipulate URI objects components",
+ "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP",
+ "php-64bit": "to improve IPV4 host parsing",
+ "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification",
+ "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present"
+ },
+ "type": "library",
"extra": {
- "class": "craft\\composer\\Plugin"
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
},
"autoload": {
"psr-4": {
- "craft\\composer\\": "src/"
+ "League\\Uri\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "Craft CMS Plugin Installer",
- "homepage": "https://craftcms.com/",
+ "authors": [
+ {
+ "name": "Ignace Nyamagana Butera",
+ "email": "nyamsprod@gmail.com",
+ "homepage": "https://nyamsprod.com"
+ }
+ ],
+ "description": "URI manipulation library",
+ "homepage": "https://uri.thephpleague.com",
"keywords": [
- "cms",
- "composer",
- "craftcms",
- "installer",
- "plugin"
+ "URN",
+ "data-uri",
+ "file-uri",
+ "ftp",
+ "hostname",
+ "http",
+ "https",
+ "middleware",
+ "parse_str",
+ "parse_url",
+ "psr-7",
+ "query-string",
+ "querystring",
+ "rfc2141",
+ "rfc3986",
+ "rfc3987",
+ "rfc6570",
+ "rfc8141",
+ "uri",
+ "uri-template",
+ "url",
+ "ws"
],
"support": {
- "docs": "https://craftcms.com/docs",
- "email": "support@craftcms.com",
- "forum": "https://craftcms.stackexchange.com/",
- "issues": "https://github.com/craftcms/cms/issues?state=open",
- "rss": "https://craftcms.com/changelog.rss",
- "source": "https://github.com/craftcms/cms"
+ "docs": "https://uri.thephpleague.com",
+ "forum": "https://thephpleague.slack.com",
+ "issues": "https://github.com/thephpleague/uri-src/issues",
+ "source": "https://github.com/thephpleague/uri/tree/7.8.1"
},
- "time": "2023-02-22T13:17:00+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/nyamsprod",
+ "type": "github"
+ }
+ ],
+ "time": "2026-03-15T20:22:25+00:00"
},
{
- "name": "craftcms/server-check",
- "version": "5.0.4",
+ "name": "league/uri-interfaces",
+ "version": "7.8.1",
"source": {
"type": "git",
- "url": "https://github.com/craftcms/server-check.git",
- "reference": "3b1f239c1cc781710978b0baa3e3bc99410d1973"
+ "url": "https://github.com/thephpleague/uri-interfaces.git",
+ "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/craftcms/server-check/zipball/3b1f239c1cc781710978b0baa3e3bc99410d1973",
- "reference": "3b1f239c1cc781710978b0baa3e3bc99410d1973",
+ "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928",
+ "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928",
"shasum": ""
},
+ "require": {
+ "ext-filter": "*",
+ "php": "^8.1",
+ "psr/http-message": "^1.1 || ^2.0"
+ },
+ "suggest": {
+ "ext-bcmath": "to improve IPV4 host parsing",
+ "ext-gmp": "to improve IPV4 host parsing",
+ "ext-intl": "to handle IDN host with the best performance",
+ "php-64bit": "to improve IPV4 host parsing",
+ "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification",
+ "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present"
+ },
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
+ },
"autoload": {
- "classmap": [
- "server/requirements"
- ]
+ "psr-4": {
+ "League\\Uri\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "Craft CMS Server Check",
- "homepage": "https://craftcms.com/",
+ "authors": [
+ {
+ "name": "Ignace Nyamagana Butera",
+ "email": "nyamsprod@gmail.com",
+ "homepage": "https://nyamsprod.com"
+ }
+ ],
+ "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI",
+ "homepage": "https://uri.thephpleague.com",
"keywords": [
- "cms",
- "craftcms",
- "requirements",
- "yii2"
+ "data-uri",
+ "file-uri",
+ "ftp",
+ "hostname",
+ "http",
+ "https",
+ "parse_str",
+ "parse_url",
+ "psr-7",
+ "query-string",
+ "querystring",
+ "rfc3986",
+ "rfc3987",
+ "rfc6570",
+ "uri",
+ "url",
+ "ws"
],
"support": {
- "docs": "https://github.com/craftcms/docs",
- "email": "support@craftcms.com",
- "forum": "https://craftcms.stackexchange.com/",
- "issues": "https://github.com/craftcms/server-check/issues?state=open",
- "rss": "https://github.com/craftcms/server-check/releases.atom",
- "source": "https://github.com/craftcms/server-check"
+ "docs": "https://uri.thephpleague.com",
+ "forum": "https://thephpleague.slack.com",
+ "issues": "https://github.com/thephpleague/uri-src/issues",
+ "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.1"
},
- "time": "2025-07-23T14:22:43+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/nyamsprod",
+ "type": "github"
+ }
+ ],
+ "time": "2026-03-08T20:05:35+00:00"
},
{
- "name": "creocoder/yii2-nested-sets",
- "version": "0.9.0",
+ "name": "maennchen/zipstream-php",
+ "version": "3.2.2",
"source": {
"type": "git",
- "url": "https://github.com/creocoder/yii2-nested-sets.git",
- "reference": "cb8635a459b6246e5a144f096b992dcc30cf9954"
+ "url": "https://github.com/maennchen/ZipStream-PHP.git",
+ "reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/creocoder/yii2-nested-sets/zipball/cb8635a459b6246e5a144f096b992dcc30cf9954",
- "reference": "cb8635a459b6246e5a144f096b992dcc30cf9954",
+ "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e",
+ "reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e",
"shasum": ""
},
"require": {
- "yiisoft/yii2": "*"
+ "ext-mbstring": "*",
+ "ext-zlib": "*",
+ "php-64bit": "^8.3"
},
- "type": "yii2-extension",
+ "require-dev": {
+ "brianium/paratest": "^7.7",
+ "ext-zip": "*",
+ "friendsofphp/php-cs-fixer": "^3.86",
+ "guzzlehttp/guzzle": "^7.5",
+ "mikey179/vfsstream": "^1.6",
+ "php-coveralls/php-coveralls": "^2.5",
+ "phpunit/phpunit": "^12.0",
+ "vimeo/psalm": "^6.0"
+ },
+ "suggest": {
+ "guzzlehttp/psr7": "^2.4",
+ "psr/http-message": "^2.0"
+ },
+ "type": "library",
"autoload": {
"psr-4": {
- "creocoder\\nestedsets\\": "src"
+ "ZipStream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Alexander Kochetov",
- "email": "creocoder@gmail.com"
+ "name": "Paul Duncan",
+ "email": "pabs@pablotron.org"
+ },
+ {
+ "name": "Jonatan Männchen",
+ "email": "jonatan@maennchen.ch"
+ },
+ {
+ "name": "Jesse Donat",
+ "email": "donatj@gmail.com"
+ },
+ {
+ "name": "András Kolesár",
+ "email": "kolesar@kolesar.hu"
}
],
- "description": "The nested sets behavior for the Yii framework",
+ "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
"keywords": [
- "nested sets",
- "yii2"
+ "stream",
+ "zip"
],
"support": {
- "issues": "https://github.com/creocoder/yii2-nested-sets/issues",
- "source": "https://github.com/creocoder/yii2-nested-sets/tree/master"
+ "issues": "https://github.com/maennchen/ZipStream-PHP/issues",
+ "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.2"
},
- "time": "2015-01-27T10:53:51+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/maennchen",
+ "type": "github"
+ }
+ ],
+ "time": "2026-04-11T18:38:28+00:00"
},
{
- "name": "dasprid/enum",
- "version": "1.0.7",
+ "name": "markbaker/complex",
+ "version": "3.0.2",
"source": {
"type": "git",
- "url": "https://github.com/DASPRiD/Enum.git",
- "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce"
+ "url": "https://github.com/MarkBaker/PHPComplex.git",
+ "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce",
- "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce",
+ "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
+ "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"shasum": ""
},
"require": {
- "php": ">=7.1 <9.0"
+ "php": "^7.2 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11",
- "squizlabs/php_codesniffer": "*"
+ "dealerdirect/phpcodesniffer-composer-installer": "dev-master",
+ "phpcompatibility/php-compatibility": "^9.3",
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
+ "squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
"psr-4": {
- "DASPRiD\\Enum\\": "src/"
+ "Complex\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-2-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Ben Scholzen 'DASPRiD'",
- "email": "mail@dasprids.de",
- "homepage": "https://dasprids.de/",
- "role": "Developer"
+ "name": "Mark Baker",
+ "email": "mark@lange.demon.co.uk"
}
],
- "description": "PHP 7.1 enum implementation",
+ "description": "PHP Class for working with complex numbers",
+ "homepage": "https://github.com/MarkBaker/PHPComplex",
"keywords": [
- "enum",
- "map"
+ "complex",
+ "mathematics"
],
"support": {
- "issues": "https://github.com/DASPRiD/Enum/issues",
- "source": "https://github.com/DASPRiD/Enum/tree/1.0.7"
+ "issues": "https://github.com/MarkBaker/PHPComplex/issues",
+ "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
},
- "time": "2025-09-16T12:23:56+00:00"
+ "time": "2022-12-06T16:21:08+00:00"
},
{
- "name": "defuse/php-encryption",
- "version": "v2.4.0",
+ "name": "markbaker/matrix",
+ "version": "3.0.1",
"source": {
"type": "git",
- "url": "https://github.com/defuse/php-encryption.git",
- "reference": "f53396c2d34225064647a05ca76c1da9d99e5828"
+ "url": "https://github.com/MarkBaker/PHPMatrix.git",
+ "reference": "728434227fe21be27ff6d86621a1b13107a2562c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/defuse/php-encryption/zipball/f53396c2d34225064647a05ca76c1da9d99e5828",
- "reference": "f53396c2d34225064647a05ca76c1da9d99e5828",
+ "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
+ "reference": "728434227fe21be27ff6d86621a1b13107a2562c",
"shasum": ""
},
"require": {
- "ext-openssl": "*",
- "paragonie/random_compat": ">= 2",
- "php": ">=5.6.0"
+ "php": "^7.1 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "^5|^6|^7|^8|^9|^10",
- "yoast/phpunit-polyfills": "^2.0.0"
+ "dealerdirect/phpcodesniffer-composer-installer": "dev-master",
+ "phpcompatibility/php-compatibility": "^9.3",
+ "phpdocumentor/phpdocumentor": "2.*",
+ "phploc/phploc": "^4.0",
+ "phpmd/phpmd": "2.*",
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
+ "sebastian/phpcpd": "^4.0",
+ "squizlabs/php_codesniffer": "^3.7"
},
- "bin": [
- "bin/generate-defuse-key"
- ],
"type": "library",
"autoload": {
"psr-4": {
- "Defuse\\Crypto\\": "src"
+ "Matrix\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -734,65 +2752,53 @@
],
"authors": [
{
- "name": "Taylor Hornby",
- "email": "taylor@defuse.ca",
- "homepage": "https://defuse.ca/"
- },
- {
- "name": "Scott Arciszewski",
- "email": "info@paragonie.com",
- "homepage": "https://paragonie.com"
+ "name": "Mark Baker",
+ "email": "mark@demon-angel.eu"
}
],
- "description": "Secure PHP Encryption Library",
+ "description": "PHP Class for working with matrices",
+ "homepage": "https://github.com/MarkBaker/PHPMatrix",
"keywords": [
- "aes",
- "authenticated encryption",
- "cipher",
- "crypto",
- "cryptography",
- "encrypt",
- "encryption",
- "openssl",
- "security",
- "symmetric key cryptography"
+ "mathematics",
+ "matrix",
+ "vector"
],
"support": {
- "issues": "https://github.com/defuse/php-encryption/issues",
- "source": "https://github.com/defuse/php-encryption/tree/v2.4.0"
+ "issues": "https://github.com/MarkBaker/PHPMatrix/issues",
+ "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
},
- "time": "2023-06-19T06:10:36+00:00"
+ "time": "2022-12-02T22:17:43+00:00"
},
{
- "name": "doctrine/collections",
- "version": "2.4.0",
+ "name": "masterminds/html5",
+ "version": "2.10.1",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/collections.git",
- "reference": "9acfeea2e8666536edff3d77c531261c63680160"
+ "url": "https://github.com/Masterminds/html5-php.git",
+ "reference": "fd5018f6815fff903946d0564977b44ce8010e29"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/collections/zipball/9acfeea2e8666536edff3d77c531261c63680160",
- "reference": "9acfeea2e8666536edff3d77c531261c63680160",
+ "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fd5018f6815fff903946d0564977b44ce8010e29",
+ "reference": "fd5018f6815fff903946d0564977b44ce8010e29",
"shasum": ""
},
"require": {
- "doctrine/deprecations": "^1",
- "php": "^8.1",
- "symfony/polyfill-php84": "^1.30"
+ "ext-dom": "*",
+ "php": ">=5.3.0"
},
"require-dev": {
- "doctrine/coding-standard": "^14",
- "ext-json": "*",
- "phpstan/phpstan": "^2.1.30",
- "phpstan/phpstan-phpunit": "^2.0.7",
- "phpunit/phpunit": "^10.5.58 || ^11.5.42 || ^12.4"
+ "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9 || ^10"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
},
- "type": "library",
"autoload": {
"psr-4": {
- "Doctrine\\Common\\Collections\\": "src"
+ "Masterminds\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -801,130 +2807,137 @@
],
"authors": [
{
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
+ "name": "Matt Butcher",
+ "email": "technosophos@gmail.com"
},
{
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com"
+ "name": "Matt Farina",
+ "email": "matt@mattfarina.com"
},
{
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com"
+ "name": "Asmir Mustafic",
+ "email": "goetas@gmail.com"
}
],
- "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.",
- "homepage": "https://www.doctrine-project.org/projects/collections.html",
+ "description": "An HTML5 parser and serializer.",
+ "homepage": "http://masterminds.github.io/html5-php",
"keywords": [
- "array",
- "collections",
- "iterators",
- "php"
+ "HTML5",
+ "dom",
+ "html",
+ "parser",
+ "querypath",
+ "serializer",
+ "xml"
],
"support": {
- "issues": "https://github.com/doctrine/collections/issues",
- "source": "https://github.com/doctrine/collections/tree/2.4.0"
+ "issues": "https://github.com/Masterminds/html5-php/issues",
+ "source": "https://github.com/Masterminds/html5-php/tree/2.10.1"
},
- "funding": [
- {
- "url": "https://www.doctrine-project.org/sponsorship.html",
- "type": "custom"
- },
- {
- "url": "https://www.patreon.com/phpdoctrine",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcollections",
- "type": "tidelift"
- }
- ],
- "time": "2025-10-25T09:18:13+00:00"
+ "time": "2026-06-23T18:43:15+00:00"
},
{
- "name": "doctrine/deprecations",
- "version": "1.1.5",
+ "name": "mikehaertl/php-shellcommand",
+ "version": "1.7.0",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/deprecations.git",
- "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38"
+ "url": "https://github.com/mikehaertl/php-shellcommand.git",
+ "reference": "e79ea528be155ffdec6f3bf1a4a46307bb49e545"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
- "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
+ "url": "https://api.github.com/repos/mikehaertl/php-shellcommand/zipball/e79ea528be155ffdec6f3bf1a4a46307bb49e545",
+ "reference": "e79ea528be155ffdec6f3bf1a4a46307bb49e545",
"shasum": ""
},
"require": {
- "php": "^7.1 || ^8.0"
- },
- "conflict": {
- "phpunit/phpunit": "<=7.5 || >=13"
+ "php": ">= 5.3.0"
},
"require-dev": {
- "doctrine/coding-standard": "^9 || ^12 || ^13",
- "phpstan/phpstan": "1.4.10 || 2.1.11",
- "phpstan/phpstan-phpunit": "^1.0 || ^2",
- "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12",
- "psr/log": "^1 || ^2 || ^3"
- },
- "suggest": {
- "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ "phpunit/phpunit": ">4.0 <=9.4"
},
"type": "library",
"autoload": {
"psr-4": {
- "Doctrine\\Deprecations\\": "src"
+ "mikehaertl\\shellcommand\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
- "homepage": "https://www.doctrine-project.org/",
+ "authors": [
+ {
+ "name": "Michael Härtl",
+ "email": "haertl.mike@gmail.com"
+ }
+ ],
+ "description": "An object oriented interface to shell commands",
+ "keywords": [
+ "shell"
+ ],
"support": {
- "issues": "https://github.com/doctrine/deprecations/issues",
- "source": "https://github.com/doctrine/deprecations/tree/1.1.5"
+ "issues": "https://github.com/mikehaertl/php-shellcommand/issues",
+ "source": "https://github.com/mikehaertl/php-shellcommand/tree/1.7.0"
},
- "time": "2025-04-07T20:06:18+00:00"
+ "time": "2023-04-19T08:25:22+00:00"
},
{
- "name": "doctrine/lexer",
- "version": "3.0.1",
+ "name": "moneyphp/money",
+ "version": "v4.9.0",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/lexer.git",
- "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd"
+ "url": "https://github.com/moneyphp/money.git",
+ "reference": "d49ee625c6ba79b9d7a228ce153b02fc1032152b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
- "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
+ "url": "https://api.github.com/repos/moneyphp/money/zipball/d49ee625c6ba79b9d7a228ce153b02fc1032152b",
+ "reference": "d49ee625c6ba79b9d7a228ce153b02fc1032152b",
"shasum": ""
},
"require": {
- "php": "^8.1"
+ "ext-bcmath": "*",
+ "ext-filter": "*",
+ "ext-json": "*",
+ "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
},
"require-dev": {
- "doctrine/coding-standard": "^12",
- "phpstan/phpstan": "^1.10",
- "phpunit/phpunit": "^10.5",
- "psalm/plugin-phpunit": "^0.18.3",
- "vimeo/psalm": "^5.21"
+ "cache/taggable-cache": "^1.1.0",
+ "doctrine/coding-standard": "^12.0",
+ "doctrine/instantiator": "^1.5.0 || ^2.0",
+ "ext-gmp": "*",
+ "ext-intl": "*",
+ "florianv/exchanger": "^2.8.1",
+ "florianv/swap": "^4.3.0",
+ "moneyphp/crypto-currencies": "^1.1.0",
+ "moneyphp/iso-currencies": "^3.4",
+ "php-http/message": "^1.16.0",
+ "php-http/mock-client": "^1.6.0",
+ "phpbench/phpbench": "^1.2.5",
+ "phpstan/extension-installer": "^1.4",
+ "phpstan/phpstan": "^2.1.9",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "phpunit/phpunit": "^10.5.9",
+ "psr/cache": "^1.0.1 || ^2.0 || ^3.0",
+ "ticketswap/phpstan-error-formatter": "^1.1"
+ },
+ "suggest": {
+ "ext-gmp": "Calculate without integer limits",
+ "ext-intl": "Format Money objects with intl",
+ "florianv/exchanger": "Exchange rates library for PHP",
+ "florianv/swap": "Exchange rates library for PHP",
+ "psr/cache-implementation": "Used for Currency caching"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
- "Doctrine\\Common\\Lexer\\": "src"
+ "Money\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -933,82 +2946,99 @@
],
"authors": [
{
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
+ "name": "Mathias Verraes",
+ "email": "mathias@verraes.net",
+ "homepage": "http://verraes.net"
},
{
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com"
},
{
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com"
+ "name": "Frederik Bosch",
+ "email": "f.bosch@genkgo.nl"
}
],
- "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
- "homepage": "https://www.doctrine-project.org/projects/lexer.html",
+ "description": "PHP implementation of Fowler's Money pattern",
+ "homepage": "http://moneyphp.org",
"keywords": [
- "annotations",
- "docblock",
- "lexer",
- "parser",
- "php"
+ "Value Object",
+ "money",
+ "vo"
],
"support": {
- "issues": "https://github.com/doctrine/lexer/issues",
- "source": "https://github.com/doctrine/lexer/tree/3.0.1"
+ "issues": "https://github.com/moneyphp/money/issues",
+ "source": "https://github.com/moneyphp/money/tree/v4.9.0"
},
- "funding": [
- {
- "url": "https://www.doctrine-project.org/sponsorship.html",
- "type": "custom"
- },
- {
- "url": "https://www.patreon.com/phpdoctrine",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
- "type": "tidelift"
- }
- ],
- "time": "2024-02-05T11:56:58+00:00"
+ "time": "2026-05-04T20:23:15+00:00"
},
{
- "name": "egulias/email-validator",
- "version": "4.0.4",
+ "name": "monolog/monolog",
+ "version": "3.10.0",
"source": {
"type": "git",
- "url": "https://github.com/egulias/EmailValidator.git",
- "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa"
+ "url": "https://github.com/Seldaek/monolog.git",
+ "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa",
- "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0",
+ "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
"shasum": ""
},
"require": {
- "doctrine/lexer": "^2.0 || ^3.0",
"php": ">=8.1",
- "symfony/polyfill-intl-idn": "^1.26"
+ "psr/log": "^2.0 || ^3.0"
+ },
+ "provide": {
+ "psr/log-implementation": "3.0.0"
},
"require-dev": {
- "phpunit/phpunit": "^10.2",
- "vimeo/psalm": "^5.12"
+ "aws/aws-sdk-php": "^3.0",
+ "doctrine/couchdb": "~1.0@dev",
+ "elasticsearch/elasticsearch": "^7 || ^8",
+ "ext-json": "*",
+ "graylog2/gelf-php": "^1.4.2 || ^2.0",
+ "guzzlehttp/guzzle": "^7.4.5",
+ "guzzlehttp/psr7": "^2.2",
+ "mongodb/mongodb": "^1.8 || ^2.0",
+ "php-amqplib/php-amqplib": "~2.4 || ^3",
+ "php-console/php-console": "^3.1.8",
+ "phpstan/phpstan": "^2",
+ "phpstan/phpstan-deprecation-rules": "^2",
+ "phpstan/phpstan-strict-rules": "^2",
+ "phpunit/phpunit": "^10.5.17 || ^11.0.7",
+ "predis/predis": "^1.1 || ^2",
+ "rollbar/rollbar": "^4.0",
+ "ruflin/elastica": "^7 || ^8",
+ "symfony/mailer": "^5.4 || ^6",
+ "symfony/mime": "^5.4 || ^6"
},
"suggest": {
- "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
+ "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+ "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+ "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
+ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+ "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
+ "ext-mbstring": "Allow to work properly with unicode symbols",
+ "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
+ "ext-openssl": "Required to send log messages using SSL",
+ "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
+ "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+ "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
+ "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
+ "rollbar/rollbar": "Allow sending log messages to Rollbar",
+ "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.0.x-dev"
+ "dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
- "Egulias\\EmailValidator\\": "src"
+ "Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1017,230 +3047,286 @@
],
"authors": [
{
- "name": "Eduardo Gulias Davis"
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "https://seld.be"
}
],
- "description": "A library for validating emails against several RFCs",
- "homepage": "https://github.com/egulias/EmailValidator",
+ "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+ "homepage": "https://github.com/Seldaek/monolog",
"keywords": [
- "email",
- "emailvalidation",
- "emailvalidator",
- "validation",
- "validator"
+ "log",
+ "logging",
+ "psr-3"
],
"support": {
- "issues": "https://github.com/egulias/EmailValidator/issues",
- "source": "https://github.com/egulias/EmailValidator/tree/4.0.4"
+ "issues": "https://github.com/Seldaek/monolog/issues",
+ "source": "https://github.com/Seldaek/monolog/tree/3.10.0"
},
"funding": [
{
- "url": "https://github.com/egulias",
+ "url": "https://github.com/Seldaek",
"type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
+ "type": "tidelift"
}
],
- "time": "2025-03-06T22:45:56+00:00"
+ "time": "2026-01-02T08:56:05+00:00"
},
{
- "name": "elvanto/litemoji",
- "version": "4.3.0",
+ "name": "myclabs/deep-copy",
+ "version": "1.13.4",
"source": {
"type": "git",
- "url": "https://github.com/elvanto/litemoji.git",
- "reference": "f13cf10686f7110a3b17d09de03050d0708840b8"
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/elvanto/litemoji/zipball/f13cf10686f7110a3b17d09de03050d0708840b8",
- "reference": "f13cf10686f7110a3b17d09de03050d0708840b8",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
+ "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
"shasum": ""
},
"require": {
- "ext-mbstring": "*",
- "php": ">=7.3"
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/collections": "<1.6.8",
+ "doctrine/common": "<2.13.3 || >=3 <3.2.2"
},
"require-dev": {
- "milesj/emojibase": "7.0.*",
- "phpunit/phpunit": "^9.0"
+ "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": {
- "LitEmoji\\": "src/"
+ "DeepCopy\\": "src/DeepCopy/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "A PHP library simplifying the conversion of unicode, HTML and shortcode emoji.",
+ "description": "Create deep copies (clones) of your objects",
"keywords": [
- "emoji",
- "php-emoji"
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
],
"support": {
- "issues": "https://github.com/elvanto/litemoji/issues",
- "source": "https://github.com/elvanto/litemoji/tree/4.3.0"
+ "issues": "https://github.com/myclabs/DeepCopy/issues",
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
},
- "time": "2022-10-28T02:32:19+00:00"
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2025-08-01T08:46:24+00:00"
},
{
- "name": "enshrined/svg-sanitize",
- "version": "0.22.0",
+ "name": "nesbot/carbon",
+ "version": "2.73.0",
"source": {
"type": "git",
- "url": "https://github.com/darylldoyle/svg-sanitizer.git",
- "reference": "0afa95ea74be155a7bcd6c6fb60c276c39984500"
+ "url": "https://github.com/CarbonPHP/carbon.git",
+ "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/darylldoyle/svg-sanitizer/zipball/0afa95ea74be155a7bcd6c6fb60c276c39984500",
- "reference": "0afa95ea74be155a7bcd6c6fb60c276c39984500",
+ "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/9228ce90e1035ff2f0db84b40ec2e023ed802075",
+ "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075",
"shasum": ""
},
"require": {
- "ext-dom": "*",
- "ext-libxml": "*",
- "php": "^7.1 || ^8.0"
+ "carbonphp/carbon-doctrine-types": "*",
+ "ext-json": "*",
+ "php": "^7.1.8 || ^8.0",
+ "psr/clock": "^1.0",
+ "symfony/polyfill-mbstring": "^1.0",
+ "symfony/polyfill-php80": "^1.16",
+ "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0"
+ },
+ "provide": {
+ "psr/clock-implementation": "1.0"
},
"require-dev": {
- "phpunit/phpunit": "^6.5 || ^8.5"
+ "doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0",
+ "doctrine/orm": "^2.7 || ^3.0",
+ "friendsofphp/php-cs-fixer": "^3.0",
+ "kylekatarnls/multi-tester": "^2.0",
+ "ondrejmirtes/better-reflection": "<6",
+ "phpmd/phpmd": "^2.9",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^0.12.99 || ^1.7.14",
+ "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20",
+ "squizlabs/php_codesniffer": "^3.4"
},
+ "bin": [
+ "bin/carbon"
+ ],
"type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Carbon\\Laravel\\ServiceProvider"
+ ]
+ },
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ },
+ "branch-alias": {
+ "dev-2.x": "2.x-dev",
+ "dev-master": "3.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
- "enshrined\\svgSanitize\\": "src"
+ "Carbon\\": "src/Carbon/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "GPL-2.0-or-later"
+ "MIT"
],
"authors": [
{
- "name": "Daryll Doyle",
- "email": "daryll@enshrined.co.uk"
+ "name": "Brian Nesbitt",
+ "email": "brian@nesbot.com",
+ "homepage": "https://markido.com"
+ },
+ {
+ "name": "kylekatarnls",
+ "homepage": "https://github.com/kylekatarnls"
}
],
- "description": "An SVG sanitizer for PHP",
+ "description": "An API extension for DateTime that supports 281 different languages.",
+ "homepage": "https://carbon.nesbot.com",
+ "keywords": [
+ "date",
+ "datetime",
+ "time"
+ ],
"support": {
- "issues": "https://github.com/darylldoyle/svg-sanitizer/issues",
- "source": "https://github.com/darylldoyle/svg-sanitizer/tree/0.22.0"
+ "docs": "https://carbon.nesbot.com/docs",
+ "issues": "https://github.com/briannesbitt/Carbon/issues",
+ "source": "https://github.com/briannesbitt/Carbon"
},
- "time": "2025-08-12T10:13:48+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/kylekatarnls",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/Carbon#sponsor",
+ "type": "opencollective"
+ },
+ {
+ "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2025-01-08T20:10:23+00:00"
},
{
- "name": "ezyang/htmlpurifier",
- "version": "v4.19.0",
+ "name": "nikic/php-parser",
+ "version": "v5.7.0",
"source": {
"type": "git",
- "url": "https://github.com/ezyang/htmlpurifier.git",
- "reference": "b287d2a16aceffbf6e0295559b39662612b77fcf"
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/b287d2a16aceffbf6e0295559b39662612b77fcf",
- "reference": "b287d2a16aceffbf6e0295559b39662612b77fcf",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82",
+ "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82",
"shasum": ""
},
"require": {
- "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
+ "ext-ctype": "*",
+ "ext-json": "*",
+ "ext-tokenizer": "*",
+ "php": ">=7.4"
},
"require-dev": {
- "cerdic/css-tidy": "^1.7 || ^2.0",
- "simpletest/simpletest": "dev-master"
- },
- "suggest": {
- "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
- "ext-bcmath": "Used for unit conversion and imagecrash protection",
- "ext-iconv": "Converts text to and from non-UTF-8 encodings",
- "ext-tidy": "Used for pretty-printing HTML"
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^9.0"
},
+ "bin": [
+ "bin/php-parse"
+ ],
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.x-dev"
+ }
+ },
"autoload": {
- "files": [
- "library/HTMLPurifier.composer.php"
- ],
- "psr-0": {
- "HTMLPurifier": "library/"
- },
- "exclude-from-classmap": [
- "/library/HTMLPurifier/Language/"
- ]
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "LGPL-2.1-or-later"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Edward Z. Yang",
- "email": "admin@htmlpurifier.org",
- "homepage": "http://ezyang.com"
+ "name": "Nikita Popov"
}
],
- "description": "Standards compliant HTML filter written in PHP",
- "homepage": "http://htmlpurifier.org/",
+ "description": "A PHP parser written in PHP",
"keywords": [
- "html"
+ "parser",
+ "php"
],
"support": {
- "issues": "https://github.com/ezyang/htmlpurifier/issues",
- "source": "https://github.com/ezyang/htmlpurifier/tree/v4.19.0"
+ "issues": "https://github.com/nikic/PHP-Parser/issues",
+ "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0"
},
- "time": "2025-10-17T16:34:55+00:00"
+ "time": "2025-12-06T11:56:16+00:00"
},
{
- "name": "guzzlehttp/guzzle",
- "version": "7.10.0",
+ "name": "paragonie/constant_time_encoding",
+ "version": "v3.1.3",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/guzzle.git",
- "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4"
+ "url": "https://github.com/paragonie/constant_time_encoding.git",
+ "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4",
- "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4",
+ "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
+ "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
"shasum": ""
},
"require": {
- "ext-json": "*",
- "guzzlehttp/promises": "^2.3",
- "guzzlehttp/psr7": "^2.8",
- "php": "^7.2.5 || ^8.0",
- "psr/http-client": "^1.0",
- "symfony/deprecation-contracts": "^2.2 || ^3.0"
- },
- "provide": {
- "psr/http-client-implementation": "1.0"
+ "php": "^8"
},
"require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.2",
- "ext-curl": "*",
- "guzzle/client-integration-tests": "3.0.2",
- "php-http/message-factory": "^1.1",
- "phpunit/phpunit": "^8.5.39 || ^9.6.20",
- "psr/log": "^1.1 || ^2.0 || ^3.0"
- },
- "suggest": {
- "ext-curl": "Required for CURL handler support",
- "ext-intl": "Required for Internationalized Domain Name (IDN) support",
- "psr/log": "Required for using the Log middleware"
+ "infection/infection": "^0",
+ "nikic/php-fuzzer": "^0",
+ "phpunit/phpunit": "^9|^10|^11",
+ "vimeo/psalm": "^4|^5|^6"
},
"type": "library",
- "extra": {
- "bamarni-bin": {
- "bin-links": true,
- "forward-command": false
- }
- },
"autoload": {
- "files": [
- "src/functions_include.php"
- ],
"psr-4": {
- "GuzzleHttp\\": "src/"
+ "ParagonIE\\ConstantTime\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1249,198 +3335,184 @@
],
"authors": [
{
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "Jeremy Lindblom",
- "email": "jeremeamia@gmail.com",
- "homepage": "https://github.com/jeremeamia"
- },
- {
- "name": "George Mponos",
- "email": "gmponos@gmail.com",
- "homepage": "https://github.com/gmponos"
- },
- {
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://github.com/sagikazarmark"
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com",
+ "role": "Maintainer"
},
{
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
+ "name": "Steve 'Sc00bz' Thomas",
+ "email": "steve@tobtu.com",
+ "homepage": "https://www.tobtu.com",
+ "role": "Original Developer"
}
],
- "description": "Guzzle is a PHP HTTP client library",
+ "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
"keywords": [
- "client",
- "curl",
- "framework",
- "http",
- "http client",
- "psr-18",
- "psr-7",
- "rest",
- "web service"
+ "base16",
+ "base32",
+ "base32_decode",
+ "base32_encode",
+ "base64",
+ "base64_decode",
+ "base64_encode",
+ "bin2hex",
+ "encoding",
+ "hex",
+ "hex2bin",
+ "rfc4648"
],
"support": {
- "issues": "https://github.com/guzzle/guzzle/issues",
- "source": "https://github.com/guzzle/guzzle/tree/7.10.0"
- },
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://github.com/Nyholm",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
- "type": "tidelift"
- }
- ],
- "time": "2025-08-23T22:36:01+00:00"
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/constant_time_encoding/issues",
+ "source": "https://github.com/paragonie/constant_time_encoding"
+ },
+ "time": "2025-09-24T15:06:41+00:00"
},
{
- "name": "guzzlehttp/promises",
- "version": "2.3.0",
+ "name": "phar-io/manifest",
+ "version": "2.0.4",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/promises.git",
- "reference": "481557b130ef3790cf82b713667b43030dc9c957"
+ "url": "https://github.com/phar-io/manifest.git",
+ "reference": "54750ef60c58e43759730615a392c31c80e23176"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957",
- "reference": "481557b130ef3790cf82b713667b43030dc9c957",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
+ "reference": "54750ef60c58e43759730615a392c31c80e23176",
"shasum": ""
},
"require": {
- "php": "^7.2.5 || ^8.0"
- },
- "require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.2",
- "phpunit/phpunit": "^8.5.44 || ^9.6.25"
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-phar": "*",
+ "ext-xmlwriter": "*",
+ "phar-io/version": "^3.0.1",
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
- "bamarni-bin": {
- "bin-links": true,
- "forward-command": false
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
- "psr-4": {
- "GuzzleHttp\\Promise\\": "src/"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
},
{
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
},
{
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
}
],
- "description": "Guzzle promises library",
- "keywords": [
- "promise"
- ],
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
"support": {
- "issues": "https://github.com/guzzle/promises/issues",
- "source": "https://github.com/guzzle/promises/tree/2.3.0"
+ "issues": "https://github.com/phar-io/manifest/issues",
+ "source": "https://github.com/phar-io/manifest/tree/2.0.4"
},
"funding": [
{
- "url": "https://github.com/GrahamCampbell",
+ "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"
},
{
- "url": "https://github.com/Nyholm",
- "type": "github"
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
},
{
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
- "type": "tidelift"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
}
],
- "time": "2025-08-22T14:34:08+00:00"
+ "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": "guzzlehttp/psr7",
- "version": "2.8.0",
+ "name": "phpdocumentor/reflection-common",
+ "version": "2.2.0",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/psr7.git",
- "reference": "21dc724a0583619cd1652f673303492272778051"
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051",
- "reference": "21dc724a0583619cd1652f673303492272778051",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"shasum": ""
},
"require": {
- "php": "^7.2.5 || ^8.0",
- "psr/http-factory": "^1.0",
- "psr/http-message": "^1.1 || ^2.0",
- "ralouphie/getallheaders": "^3.0"
- },
- "provide": {
- "psr/http-factory-implementation": "1.0",
- "psr/http-message-implementation": "1.0"
- },
- "require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.2",
- "http-interop/http-factory-tests": "0.9.0",
- "phpunit/phpunit": "^8.5.44 || ^9.6.25"
- },
- "suggest": {
- "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
- "bamarni-bin": {
- "bin-links": true,
- "forward-command": false
+ "branch-alias": {
+ "dev-2.x": "2.x-dev"
}
},
"autoload": {
"psr-4": {
- "GuzzleHttp\\Psr7\\": "src/"
+ "phpDocumentor\\Reflection\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1449,107 +3521,66 @@
],
"authors": [
{
- "name": "Graham Campbell",
- "email": "hello@gjcampbell.co.uk",
- "homepage": "https://github.com/GrahamCampbell"
- },
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "George Mponos",
- "email": "gmponos@gmail.com",
- "homepage": "https://github.com/gmponos"
- },
- {
- "name": "Tobias Nyholm",
- "email": "tobias.nyholm@gmail.com",
- "homepage": "https://github.com/Nyholm"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://github.com/sagikazarmark"
- },
- {
- "name": "Tobias Schultze",
- "email": "webmaster@tubo-world.de",
- "homepage": "https://github.com/Tobion"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com",
- "homepage": "https://sagikazarmark.hu"
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
}
],
- "description": "PSR-7 message implementation that also provides common utility methods",
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
"keywords": [
- "http",
- "message",
- "psr-7",
- "request",
- "response",
- "stream",
- "uri",
- "url"
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
],
"support": {
- "issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/2.8.0"
+ "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
},
- "funding": [
- {
- "url": "https://github.com/GrahamCampbell",
- "type": "github"
- },
- {
- "url": "https://github.com/Nyholm",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
- "type": "tidelift"
- }
- ],
- "time": "2025-08-23T21:21:41+00:00"
+ "time": "2020-06-27T09:03:43+00:00"
},
{
- "name": "illuminate/collections",
- "version": "v10.49.0",
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "5.6.7",
"source": {
"type": "git",
- "url": "https://github.com/illuminate/collections.git",
- "reference": "6ae9c74fa92d4e1824d1b346cd435e8eacdc3232"
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "31a105931bc8ffa3a123383829772e832fd8d903"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/illuminate/collections/zipball/6ae9c74fa92d4e1824d1b346cd435e8eacdc3232",
- "reference": "6ae9c74fa92d4e1824d1b346cd435e8eacdc3232",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/31a105931bc8ffa3a123383829772e832fd8d903",
+ "reference": "31a105931bc8ffa3a123383829772e832fd8d903",
"shasum": ""
},
"require": {
- "illuminate/conditionable": "^10.0",
- "illuminate/contracts": "^10.0",
- "illuminate/macroable": "^10.0",
- "php": "^8.1"
+ "doctrine/deprecations": "^1.1",
+ "ext-filter": "*",
+ "php": "^7.4 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.2",
+ "phpdocumentor/type-resolver": "^1.7",
+ "phpstan/phpdoc-parser": "^1.7|^2.0",
+ "webmozart/assert": "^1.9.1 || ^2"
},
- "suggest": {
- "symfony/var-dumper": "Required to use the dump method (^6.2)."
+ "require-dev": {
+ "mockery/mockery": "~1.3.5 || ~1.6.0",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-mockery": "^1.1",
+ "phpstan/phpstan-webmozart-assert": "^1.2",
+ "phpunit/phpunit": "^9.5",
+ "psalm/phar": "^5.26"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "10.x-dev"
+ "dev-master": "5.x-dev"
}
},
"autoload": {
- "files": [
- "helpers.php"
- ],
"psr-4": {
- "Illuminate\\Support\\": ""
+ "phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1558,44 +3589,60 @@
],
"authors": [
{
- "name": "Taylor Otwell",
- "email": "taylor@laravel.com"
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ },
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
}
],
- "description": "The Illuminate Collections package.",
- "homepage": "https://laravel.com",
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"support": {
- "issues": "https://github.com/laravel/framework/issues",
- "source": "https://github.com/laravel/framework"
+ "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.7"
},
- "time": "2025-09-08T19:05:53+00:00"
+ "time": "2026-03-18T20:47:46+00:00"
},
{
- "name": "illuminate/conditionable",
- "version": "v10.49.0",
+ "name": "phpdocumentor/type-resolver",
+ "version": "1.12.0",
"source": {
"type": "git",
- "url": "https://github.com/illuminate/conditionable.git",
- "reference": "47c700320b7a419f0d188d111f3bbed978fcbd3f"
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/illuminate/conditionable/zipball/47c700320b7a419f0d188d111f3bbed978fcbd3f",
- "reference": "47c700320b7a419f0d188d111f3bbed978fcbd3f",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195",
+ "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195",
"shasum": ""
},
"require": {
- "php": "^8.0.2"
+ "doctrine/deprecations": "^1.0",
+ "php": "^7.3 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.0",
+ "phpstan/phpdoc-parser": "^1.18|^2.0"
+ },
+ "require-dev": {
+ "ext-tokenizer": "*",
+ "phpbench/phpbench": "^1.2",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpunit/phpunit": "^9.5",
+ "rector/rector": "^0.13.9",
+ "vimeo/psalm": "^4.25"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "10.x-dev"
+ "dev-1.x": "1.x-dev"
}
},
"autoload": {
"psr-4": {
- "Illuminate\\Support\\": ""
+ "phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1604,46 +3651,79 @@
],
"authors": [
{
- "name": "Taylor Otwell",
- "email": "taylor@laravel.com"
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
}
],
- "description": "The Illuminate Conditionable package.",
- "homepage": "https://laravel.com",
+ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": {
- "issues": "https://github.com/laravel/framework/issues",
- "source": "https://github.com/laravel/framework"
+ "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0"
},
- "time": "2025-03-24T11:47:24+00:00"
+ "time": "2025-11-21T15:09:14+00:00"
},
{
- "name": "illuminate/contracts",
- "version": "v10.49.0",
+ "name": "phpoffice/phpspreadsheet",
+ "version": "5.8.0",
"source": {
"type": "git",
- "url": "https://github.com/illuminate/contracts.git",
- "reference": "2393ef579e020d88e24283913c815c3e2c143323"
+ "url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
+ "reference": "01964d92536edf1a3a874b9580a52824bebf6fbb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/illuminate/contracts/zipball/2393ef579e020d88e24283913c815c3e2c143323",
- "reference": "2393ef579e020d88e24283913c815c3e2c143323",
+ "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/01964d92536edf1a3a874b9580a52824bebf6fbb",
+ "reference": "01964d92536edf1a3a874b9580a52824bebf6fbb",
"shasum": ""
},
"require": {
+ "composer/pcre": "^1||^2||^3",
+ "ext-ctype": "*",
+ "ext-dom": "*",
+ "ext-fileinfo": "*",
+ "ext-filter": "*",
+ "ext-gd": "*",
+ "ext-iconv": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-simplexml": "*",
+ "ext-xml": "*",
+ "ext-xmlreader": "*",
+ "ext-xmlwriter": "*",
+ "ext-zip": "*",
+ "ext-zlib": "*",
+ "maennchen/zipstream-php": "^2.1 || ^3.0",
+ "markbaker/complex": "^3.0",
+ "markbaker/matrix": "^3.0",
"php": "^8.1",
- "psr/container": "^1.1.1|^2.0.1",
- "psr/simple-cache": "^1.0|^2.0|^3.0"
+ "psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "10.x-dev"
- }
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "dev-main",
+ "dompdf/dompdf": "^2.0 || ^3.0",
+ "ext-intl": "*",
+ "friendsofphp/php-cs-fixer": "^3.2",
+ "mitoteam/jpgraph": "^10.5",
+ "mpdf/mpdf": "^8.1.1",
+ "phpcompatibility/php-compatibility": "^9.3",
+ "phpstan/phpstan": "^1.1 || ^2.0",
+ "phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0",
+ "phpstan/phpstan-phpunit": "^1.0 || ^2.0",
+ "phpunit/phpunit": "^10.5",
+ "squizlabs/php_codesniffer": "^3.7",
+ "tecnickcom/tcpdf": "^6.5"
+ },
+ "suggest": {
+ "dompdf/dompdf": "Option for rendering PDF with PDF Writer",
+ "ext-intl": "PHP Internationalization Functions, required for NumberFormat Wizard and StringHelper::setLocale()",
+ "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
+ "mpdf/mpdf": "Option for rendering PDF with PDF Writer",
+ "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
},
+ "type": "library",
"autoload": {
"psr-4": {
- "Illuminate\\Contracts\\": ""
+ "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1652,638 +3732,648 @@
],
"authors": [
{
- "name": "Taylor Otwell",
- "email": "taylor@laravel.com"
+ "name": "Maarten Balliauw",
+ "homepage": "https://blog.maartenballiauw.be"
+ },
+ {
+ "name": "Mark Baker",
+ "homepage": "https://markbakeruk.net"
+ },
+ {
+ "name": "Franck Lefevre",
+ "homepage": "https://rootslabs.net"
+ },
+ {
+ "name": "Erik Tilt"
+ },
+ {
+ "name": "Adrien Crivelli"
+ },
+ {
+ "name": "Owen Leibman"
}
],
- "description": "The Illuminate Contracts package.",
- "homepage": "https://laravel.com",
+ "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
+ "homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
+ "keywords": [
+ "OpenXML",
+ "excel",
+ "gnumeric",
+ "ods",
+ "php",
+ "spreadsheet",
+ "xls",
+ "xlsx"
+ ],
"support": {
- "issues": "https://github.com/laravel/framework/issues",
- "source": "https://github.com/laravel/framework"
+ "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
+ "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.8.0"
},
- "time": "2025-03-24T11:47:24+00:00"
+ "time": "2026-06-07T03:51:10+00:00"
},
{
- "name": "illuminate/macroable",
- "version": "v10.49.0",
+ "name": "phpstan/phpdoc-parser",
+ "version": "2.3.2",
"source": {
"type": "git",
- "url": "https://github.com/illuminate/macroable.git",
- "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27"
+ "url": "https://github.com/phpstan/phpdoc-parser.git",
+ "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/illuminate/macroable/zipball/dff667a46ac37b634dcf68909d9d41e94dc97c27",
- "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a",
+ "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a",
"shasum": ""
},
"require": {
- "php": "^8.1"
+ "php": "^7.4 || ^8.0"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "10.x-dev"
- }
+ "require-dev": {
+ "doctrine/annotations": "^2.0",
+ "nikic/php-parser": "^5.3.0",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "phpstan/phpstan-strict-rules": "^2.0",
+ "phpunit/phpunit": "^9.6",
+ "symfony/process": "^5.2"
},
+ "type": "library",
"autoload": {
"psr-4": {
- "Illuminate\\Support\\": ""
+ "PHPStan\\PhpDocParser\\": [
+ "src/"
+ ]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "authors": [
- {
- "name": "Taylor Otwell",
- "email": "taylor@laravel.com"
- }
- ],
- "description": "The Illuminate Macroable package.",
- "homepage": "https://laravel.com",
+ "description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
- "issues": "https://github.com/laravel/framework/issues",
- "source": "https://github.com/laravel/framework"
+ "issues": "https://github.com/phpstan/phpdoc-parser/issues",
+ "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2"
},
- "time": "2023-06-05T12:46:42+00:00"
+ "time": "2026-01-25T14:56:51+00:00"
},
{
- "name": "laravel/pint",
- "version": "v1.25.1",
+ "name": "phpunit/php-code-coverage",
+ "version": "11.0.12",
"source": {
"type": "git",
- "url": "https://github.com/laravel/pint.git",
- "reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9"
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/pint/zipball/5016e263f95d97670d71b9a987bd8996ade6d8d9",
- "reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2c1ed04922802c15e1de5d7447b4856de949cf56",
+ "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56",
"shasum": ""
},
"require": {
- "ext-json": "*",
- "ext-mbstring": "*",
- "ext-tokenizer": "*",
- "ext-xml": "*",
- "php": "^8.2.0"
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-xmlwriter": "*",
+ "nikic/php-parser": "^5.7.0",
+ "php": ">=8.2",
+ "phpunit/php-file-iterator": "^5.1.0",
+ "phpunit/php-text-template": "^4.0.1",
+ "sebastian/code-unit-reverse-lookup": "^4.0.1",
+ "sebastian/complexity": "^4.0.1",
+ "sebastian/environment": "^7.2.1",
+ "sebastian/lines-of-code": "^3.0.1",
+ "sebastian/version": "^5.0.2",
+ "theseer/tokenizer": "^1.3.1"
},
"require-dev": {
- "friendsofphp/php-cs-fixer": "^3.87.2",
- "illuminate/view": "^11.46.0",
- "larastan/larastan": "^3.7.1",
- "laravel-zero/framework": "^11.45.0",
- "mockery/mockery": "^1.6.12",
- "nunomaduro/termwind": "^2.3.1",
- "pestphp/pest": "^2.36.0"
+ "phpunit/phpunit": "^11.5.46"
},
- "bin": [
- "builds/pint"
- ],
- "type": "project",
- "autoload": {
- "psr-4": {
- "App\\": "app/",
- "Database\\Seeders\\": "database/seeders/",
- "Database\\Factories\\": "database/factories/"
+ "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": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Nuno Maduro",
- "email": "enunomaduro@gmail.com"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "An opinionated code formatter for PHP.",
- "homepage": "https://laravel.com",
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
"keywords": [
- "format",
- "formatter",
- "lint",
- "linter",
- "php"
+ "coverage",
+ "testing",
+ "xunit"
],
"support": {
- "issues": "https://github.com/laravel/pint/issues",
- "source": "https://github.com/laravel/pint"
+ "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+ "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.12"
},
- "time": "2025-09-19T02:57:12+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ },
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2025-12-24T07:01:01+00:00"
},
{
- "name": "lcobucci/clock",
- "version": "3.5.0",
+ "name": "phpunit/php-file-iterator",
+ "version": "5.1.1",
"source": {
"type": "git",
- "url": "https://github.com/lcobucci/clock.git",
- "reference": "a3139d9e97d47826f27e6a17bb63f13621f86058"
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/lcobucci/clock/zipball/a3139d9e97d47826f27e6a17bb63f13621f86058",
- "reference": "a3139d9e97d47826f27e6a17bb63f13621f86058",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/2f3a64888c814fc235386b7387dd5b5ed92ad903",
+ "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903",
"shasum": ""
},
"require": {
- "php": "~8.3.0 || ~8.4.0 || ~8.5.0",
- "psr/clock": "^1.0"
- },
- "provide": {
- "psr/clock-implementation": "1.0"
+ "php": ">=8.2"
},
"require-dev": {
- "infection/infection": "^0.31",
- "lcobucci/coding-standard": "^11.2.0",
- "phpstan/extension-installer": "^1.3.1",
- "phpstan/phpstan": "^2.0.0",
- "phpstan/phpstan-deprecation-rules": "^2.0.0",
- "phpstan/phpstan-phpunit": "^2.0.0",
- "phpstan/phpstan-strict-rules": "^2.0.0",
- "phpunit/phpunit": "^12.0.0"
+ "phpunit/phpunit": "^11.3"
},
"type": "library",
- "autoload": {
- "psr-4": {
- "Lcobucci\\Clock\\": "src"
+ "extra": {
+ "branch-alias": {
+ "dev-main": "5.1-dev"
}
},
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Luís Cobucci",
- "email": "lcobucci@gmail.com"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "Yet another clock abstraction",
+ "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/lcobucci/clock/issues",
- "source": "https://github.com/lcobucci/clock/tree/3.5.0"
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.1"
},
"funding": [
{
- "url": "https://github.com/lcobucci",
+ "url": "https://github.com/sebastianbergmann",
"type": "github"
},
{
- "url": "https://www.patreon.com/lcobucci",
- "type": "patreon"
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator",
+ "type": "tidelift"
}
],
- "time": "2025-10-27T09:03:17+00:00"
+ "time": "2026-02-02T13:52:54+00:00"
},
{
- "name": "league/uri",
- "version": "7.5.1",
+ "name": "phpunit/php-invoker",
+ "version": "5.0.1",
"source": {
"type": "git",
- "url": "https://github.com/thephpleague/uri.git",
- "reference": "81fb5145d2644324614cc532b28efd0215bda430"
+ "url": "https://github.com/sebastianbergmann/php-invoker.git",
+ "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430",
- "reference": "81fb5145d2644324614cc532b28efd0215bda430",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2",
+ "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2",
"shasum": ""
},
"require": {
- "league/uri-interfaces": "^7.5",
- "php": "^8.1"
+ "php": ">=8.2"
},
- "conflict": {
- "league/uri-schemes": "^1.0"
+ "require-dev": {
+ "ext-pcntl": "*",
+ "phpunit/phpunit": "^11.0"
},
"suggest": {
- "ext-bcmath": "to improve IPV4 host parsing",
- "ext-fileinfo": "to create Data URI from file contennts",
- "ext-gmp": "to improve IPV4 host parsing",
- "ext-intl": "to handle IDN host with the best performance",
- "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain",
- "league/uri-components": "Needed to easily manipulate URI objects components",
- "php-64bit": "to improve IPV4 host parsing",
- "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present"
+ "ext-pcntl": "*"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "7.x-dev"
+ "dev-main": "5.0-dev"
}
},
"autoload": {
- "psr-4": {
- "League\\Uri\\": ""
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Ignace Nyamagana Butera",
- "email": "nyamsprod@gmail.com",
- "homepage": "https://nyamsprod.com"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "URI manipulation library",
- "homepage": "https://uri.thephpleague.com",
+ "description": "Invoke callables with a timeout",
+ "homepage": "https://github.com/sebastianbergmann/php-invoker/",
"keywords": [
- "data-uri",
- "file-uri",
- "ftp",
- "hostname",
- "http",
- "https",
- "middleware",
- "parse_str",
- "parse_url",
- "psr-7",
- "query-string",
- "querystring",
- "rfc3986",
- "rfc3987",
- "rfc6570",
- "uri",
- "uri-template",
- "url",
- "ws"
+ "process"
],
"support": {
- "docs": "https://uri.thephpleague.com",
- "forum": "https://thephpleague.slack.com",
- "issues": "https://github.com/thephpleague/uri-src/issues",
- "source": "https://github.com/thephpleague/uri/tree/7.5.1"
+ "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/sponsors/nyamsprod",
+ "url": "https://github.com/sebastianbergmann",
"type": "github"
}
],
- "time": "2024-12-08T08:40:02+00:00"
+ "time": "2024-07-03T05:07:44+00:00"
},
{
- "name": "league/uri-interfaces",
- "version": "7.5.0",
+ "name": "phpunit/php-text-template",
+ "version": "4.0.1",
"source": {
"type": "git",
- "url": "https://github.com/thephpleague/uri-interfaces.git",
- "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742"
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742",
- "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742",
- "shasum": ""
- },
- "require": {
- "ext-filter": "*",
- "php": "^8.1",
- "psr/http-factory": "^1",
- "psr/http-message": "^1.1 || ^2.0"
- },
- "suggest": {
- "ext-bcmath": "to improve IPV4 host parsing",
- "ext-gmp": "to improve IPV4 host parsing",
- "ext-intl": "to handle IDN host with the best performance",
- "php-64bit": "to improve IPV4 host parsing",
- "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present"
+ "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-master": "7.x-dev"
+ "dev-main": "4.0-dev"
}
},
"autoload": {
- "psr-4": {
- "League\\Uri\\": ""
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Ignace Nyamagana Butera",
- "email": "nyamsprod@gmail.com",
- "homepage": "https://nyamsprod.com"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "Common interfaces and classes for URI representation and interaction",
- "homepage": "https://uri.thephpleague.com",
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
"keywords": [
- "data-uri",
- "file-uri",
- "ftp",
- "hostname",
- "http",
- "https",
- "parse_str",
- "parse_url",
- "psr-7",
- "query-string",
- "querystring",
- "rfc3986",
- "rfc3987",
- "rfc6570",
- "uri",
- "url",
- "ws"
+ "template"
],
"support": {
- "docs": "https://uri.thephpleague.com",
- "forum": "https://thephpleague.slack.com",
- "issues": "https://github.com/thephpleague/uri-src/issues",
- "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0"
+ "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/sponsors/nyamsprod",
+ "url": "https://github.com/sebastianbergmann",
"type": "github"
}
],
- "time": "2024-12-08T08:18:47+00:00"
+ "time": "2024-07-03T05:08:43+00:00"
},
{
- "name": "masterminds/html5",
- "version": "2.10.0",
+ "name": "phpunit/php-timer",
+ "version": "7.0.1",
"source": {
"type": "git",
- "url": "https://github.com/Masterminds/html5-php.git",
- "reference": "fcf91eb64359852f00d921887b219479b4f21251"
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251",
- "reference": "fcf91eb64359852f00d921887b219479b4f21251",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3",
+ "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3",
"shasum": ""
},
"require": {
- "ext-dom": "*",
- "php": ">=5.3.0"
+ "php": ">=8.2"
},
"require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
+ "phpunit/phpunit": "^11.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.7-dev"
+ "dev-main": "7.0-dev"
}
},
"autoload": {
- "psr-4": {
- "Masterminds\\": "src"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Matt Butcher",
- "email": "technosophos@gmail.com"
- },
- {
- "name": "Matt Farina",
- "email": "matt@mattfarina.com"
- },
- {
- "name": "Asmir Mustafic",
- "email": "goetas@gmail.com"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "An HTML5 parser and serializer.",
- "homepage": "http://masterminds.github.io/html5-php",
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
"keywords": [
- "HTML5",
- "dom",
- "html",
- "parser",
- "querypath",
- "serializer",
- "xml"
+ "timer"
],
"support": {
- "issues": "https://github.com/Masterminds/html5-php/issues",
- "source": "https://github.com/Masterminds/html5-php/tree/2.10.0"
+ "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"
},
- "time": "2025-07-25T09:04:22+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T05:09:35+00:00"
},
{
- "name": "mikehaertl/php-shellcommand",
- "version": "1.7.0",
+ "name": "phpunit/phpunit",
+ "version": "11.5.55",
"source": {
"type": "git",
- "url": "https://github.com/mikehaertl/php-shellcommand.git",
- "reference": "e79ea528be155ffdec6f3bf1a4a46307bb49e545"
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mikehaertl/php-shellcommand/zipball/e79ea528be155ffdec6f3bf1a4a46307bb49e545",
- "reference": "e79ea528be155ffdec6f3bf1a4a46307bb49e545",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/adc7262fccc12de2b30f12a8aa0b33775d814f00",
+ "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00",
"shasum": ""
},
"require": {
- "php": ">= 5.3.0"
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "ext-xmlwriter": "*",
+ "myclabs/deep-copy": "^1.13.4",
+ "phar-io/manifest": "^2.0.4",
+ "phar-io/version": "^3.2.1",
+ "php": ">=8.2",
+ "phpunit/php-code-coverage": "^11.0.12",
+ "phpunit/php-file-iterator": "^5.1.1",
+ "phpunit/php-invoker": "^5.0.1",
+ "phpunit/php-text-template": "^4.0.1",
+ "phpunit/php-timer": "^7.0.1",
+ "sebastian/cli-parser": "^3.0.2",
+ "sebastian/code-unit": "^3.0.3",
+ "sebastian/comparator": "^6.3.3",
+ "sebastian/diff": "^6.0.2",
+ "sebastian/environment": "^7.2.1",
+ "sebastian/exporter": "^6.3.2",
+ "sebastian/global-state": "^7.0.2",
+ "sebastian/object-enumerator": "^6.0.1",
+ "sebastian/recursion-context": "^6.0.3",
+ "sebastian/type": "^5.1.3",
+ "sebastian/version": "^5.0.2",
+ "staabm/side-effects-detector": "^1.0.5"
},
- "require-dev": {
- "phpunit/phpunit": ">4.0 <=9.4"
+ "suggest": {
+ "ext-soap": "To be able to generate mocks based on WSDL files"
},
+ "bin": [
+ "phpunit"
+ ],
"type": "library",
- "autoload": {
- "psr-4": {
- "mikehaertl\\shellcommand\\": "src/"
+ "extra": {
+ "branch-alias": {
+ "dev-main": "11.5-dev"
}
},
+ "autoload": {
+ "files": [
+ "src/Framework/Assert/Functions.php"
+ ],
+ "classmap": [
+ "src/"
+ ]
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Michael Härtl",
- "email": "haertl.mike@gmail.com"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "An object oriented interface to shell commands",
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
"keywords": [
- "shell"
+ "phpunit",
+ "testing",
+ "xunit"
],
"support": {
- "issues": "https://github.com/mikehaertl/php-shellcommand/issues",
- "source": "https://github.com/mikehaertl/php-shellcommand/tree/1.7.0"
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.55"
},
- "time": "2023-04-19T08:25:22+00:00"
+ "funding": [
+ {
+ "url": "https://phpunit.de/sponsors.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ },
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-02-18T12:37:06+00:00"
},
{
- "name": "moneyphp/money",
- "version": "v4.8.0",
+ "name": "pixelandtonic/graphql-php",
+ "version": "v14.11.10.1",
"source": {
"type": "git",
- "url": "https://github.com/moneyphp/money.git",
- "reference": "b358727ea5a5cd2d7475e59c31dfc352440ae7ec"
+ "url": "https://github.com/pixelandtonic/graphql-php.git",
+ "reference": "fdb4a288878fc9ee449245e17209d676fc7c57fd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/moneyphp/money/zipball/b358727ea5a5cd2d7475e59c31dfc352440ae7ec",
- "reference": "b358727ea5a5cd2d7475e59c31dfc352440ae7ec",
+ "url": "https://api.github.com/repos/pixelandtonic/graphql-php/zipball/fdb4a288878fc9ee449245e17209d676fc7c57fd",
+ "reference": "fdb4a288878fc9ee449245e17209d676fc7c57fd",
"shasum": ""
},
"require": {
- "ext-bcmath": "*",
- "ext-filter": "*",
"ext-json": "*",
- "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
+ "ext-mbstring": "*",
+ "php": "^7.1 || ^8"
},
"require-dev": {
- "cache/taggable-cache": "^1.1.0",
- "doctrine/coding-standard": "^12.0",
- "doctrine/instantiator": "^1.5.0 || ^2.0",
- "ext-gmp": "*",
- "ext-intl": "*",
- "florianv/exchanger": "^2.8.1",
- "florianv/swap": "^4.3.0",
- "moneyphp/crypto-currencies": "^1.1.0",
- "moneyphp/iso-currencies": "^3.4",
- "php-http/message": "^1.16.0",
- "php-http/mock-client": "^1.6.0",
- "phpbench/phpbench": "^1.2.5",
- "phpstan/extension-installer": "^1.4",
- "phpstan/phpstan": "^2.1.9",
- "phpstan/phpstan-phpunit": "^2.0",
- "phpunit/phpunit": "^10.5.9",
- "psr/cache": "^1.0.1 || ^2.0 || ^3.0",
- "ticketswap/phpstan-error-formatter": "^1.1"
+ "amphp/amp": "^2.3",
+ "doctrine/coding-standard": "^6.0",
+ "nyholm/psr7": "^1.2",
+ "phpbench/phpbench": "^1.2",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "0.12.82",
+ "phpstan/phpstan-phpunit": "0.12.18",
+ "phpstan/phpstan-strict-rules": "0.12.9",
+ "phpunit/phpunit": "^7.2 || ^8.5",
+ "psr/http-message": "^1.0",
+ "react/promise": "2.*",
+ "simpod/php-coveralls-mirror": "^3.0"
},
"suggest": {
- "ext-gmp": "Calculate without integer limits",
- "ext-intl": "Format Money objects with intl",
- "florianv/exchanger": "Exchange rates library for PHP",
- "florianv/swap": "Exchange rates library for PHP",
- "psr/cache-implementation": "Used for Currency caching"
+ "psr/http-message": "To use standard GraphQL server",
+ "react/promise": "To leverage async resolving on React PHP platform"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Money\\": "src/"
+ "GraphQL\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "authors": [
- {
- "name": "Mathias Verraes",
- "email": "mathias@verraes.net",
- "homepage": "http://verraes.net"
- },
- {
- "name": "Márk Sági-Kazár",
- "email": "mark.sagikazar@gmail.com"
- },
- {
- "name": "Frederik Bosch",
- "email": "f.bosch@genkgo.nl"
- }
- ],
- "description": "PHP implementation of Fowler's Money pattern",
- "homepage": "http://moneyphp.org",
+ "description": "A PHP port of GraphQL reference implementation",
+ "homepage": "https://github.com/webonyx/graphql-php",
"keywords": [
- "Value Object",
- "money",
- "vo"
+ "api",
+ "graphql"
],
"support": {
- "issues": "https://github.com/moneyphp/money/issues",
- "source": "https://github.com/moneyphp/money/tree/v4.8.0"
+ "source": "https://github.com/pixelandtonic/graphql-php/tree/v14.11.10.1"
},
- "time": "2025-10-23T07:55:09+00:00"
+ "funding": [
+ {
+ "url": "https://opencollective.com/webonyx-graphql-php",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2026-04-14T15:27:52+00:00"
},
{
- "name": "monolog/monolog",
- "version": "3.9.0",
+ "name": "pixelandtonic/imagine",
+ "version": "1.5.2.1",
"source": {
"type": "git",
- "url": "https://github.com/Seldaek/monolog.git",
- "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6"
+ "url": "https://github.com/pixelandtonic/Imagine.git",
+ "reference": "8e6c5cf929400142724b31482da51dc556277e15"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6",
- "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6",
+ "url": "https://api.github.com/repos/pixelandtonic/Imagine/zipball/8e6c5cf929400142724b31482da51dc556277e15",
+ "reference": "8e6c5cf929400142724b31482da51dc556277e15",
"shasum": ""
},
"require": {
- "php": ">=8.1",
- "psr/log": "^2.0 || ^3.0"
- },
- "provide": {
- "psr/log-implementation": "3.0.0"
+ "php": ">=7.1"
},
"require-dev": {
- "aws/aws-sdk-php": "^3.0",
- "doctrine/couchdb": "~1.0@dev",
- "elasticsearch/elasticsearch": "^7 || ^8",
- "ext-json": "*",
- "graylog2/gelf-php": "^1.4.2 || ^2.0",
- "guzzlehttp/guzzle": "^7.4.5",
- "guzzlehttp/psr7": "^2.2",
- "mongodb/mongodb": "^1.8",
- "php-amqplib/php-amqplib": "~2.4 || ^3",
- "php-console/php-console": "^3.1.8",
- "phpstan/phpstan": "^2",
- "phpstan/phpstan-deprecation-rules": "^2",
- "phpstan/phpstan-strict-rules": "^2",
- "phpunit/phpunit": "^10.5.17 || ^11.0.7",
- "predis/predis": "^1.1 || ^2",
- "rollbar/rollbar": "^4.0",
- "ruflin/elastica": "^7 || ^8",
- "symfony/mailer": "^5.4 || ^6",
- "symfony/mime": "^5.4 || ^6"
- },
- "suggest": {
- "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
- "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
- "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
- "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
- "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
- "ext-mbstring": "Allow to work properly with unicode symbols",
- "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
- "ext-openssl": "Required to send log messages using SSL",
- "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
- "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
- "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
- "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
- "rollbar/rollbar": "Allow sending log messages to Rollbar",
- "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
+ "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.4 || ^9.3"
+ },
+ "suggest": {
+ "ext-exif": "to read EXIF metadata",
+ "ext-gd": "to use the GD implementation",
+ "ext-gmagick": "to use the Gmagick implementation",
+ "ext-imagick": "to use the Imagick implementation"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "3.x-dev"
+ "dev-develop": "1.x-dev"
}
},
"autoload": {
"psr-4": {
- "Monolog\\": "src/Monolog"
+ "Imagine\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2292,61 +4382,50 @@
],
"authors": [
{
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "https://seld.be"
+ "name": "Bulat Shakirzyanov",
+ "email": "mallluhuct@gmail.com",
+ "homepage": "http://avalanche123.com"
}
],
- "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
- "homepage": "https://github.com/Seldaek/monolog",
+ "description": "Image processing for PHP",
+ "homepage": "http://imagine.readthedocs.org/",
"keywords": [
- "log",
- "logging",
- "psr-3"
+ "drawing",
+ "graphics",
+ "image manipulation",
+ "image processing"
],
"support": {
- "issues": "https://github.com/Seldaek/monolog/issues",
- "source": "https://github.com/Seldaek/monolog/tree/3.9.0"
+ "source": "https://github.com/pixelandtonic/Imagine/tree/1.5.2.1"
},
- "funding": [
- {
- "url": "https://github.com/Seldaek",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
- "type": "tidelift"
- }
- ],
- "time": "2025-03-24T10:02:05+00:00"
+ "time": "2026-02-25T23:13:43+00:00"
},
{
- "name": "paragonie/constant_time_encoding",
- "version": "v3.1.3",
+ "name": "pragmarx/google2fa",
+ "version": "v8.0.3",
"source": {
"type": "git",
- "url": "https://github.com/paragonie/constant_time_encoding.git",
- "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77"
+ "url": "https://github.com/antonioribeiro/google2fa.git",
+ "reference": "6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
- "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
+ "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad",
+ "reference": "6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad",
"shasum": ""
},
"require": {
- "php": "^8"
+ "paragonie/constant_time_encoding": "^1.0|^2.0|^3.0",
+ "php": "^7.1|^8.0"
},
"require-dev": {
- "infection/infection": "^0",
- "nikic/php-fuzzer": "^0",
- "phpunit/phpunit": "^9|^10|^11",
- "vimeo/psalm": "^4|^5|^6"
+ "phpstan/phpstan": "^1.9",
+ "phpunit/phpunit": "^7.5.15|^8.5|^9.0"
},
"type": "library",
"autoload": {
"psr-4": {
- "ParagonIE\\ConstantTime\\": "src/"
+ "PragmaRX\\Google2FA\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2355,116 +4434,126 @@
],
"authors": [
{
- "name": "Paragon Initiative Enterprises",
- "email": "security@paragonie.com",
- "homepage": "https://paragonie.com",
- "role": "Maintainer"
- },
- {
- "name": "Steve 'Sc00bz' Thomas",
- "email": "steve@tobtu.com",
- "homepage": "https://www.tobtu.com",
- "role": "Original Developer"
+ "name": "Antonio Carlos Ribeiro",
+ "email": "acr@antoniocarlosribeiro.com",
+ "role": "Creator & Designer"
}
],
- "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
+ "description": "A One Time Password Authentication package, compatible with Google Authenticator.",
"keywords": [
- "base16",
- "base32",
- "base32_decode",
- "base32_encode",
- "base64",
- "base64_decode",
- "base64_encode",
- "bin2hex",
- "encoding",
- "hex",
- "hex2bin",
- "rfc4648"
+ "2fa",
+ "Authentication",
+ "Two Factor Authentication",
+ "google2fa"
],
"support": {
- "email": "info@paragonie.com",
- "issues": "https://github.com/paragonie/constant_time_encoding/issues",
- "source": "https://github.com/paragonie/constant_time_encoding"
+ "issues": "https://github.com/antonioribeiro/google2fa/issues",
+ "source": "https://github.com/antonioribeiro/google2fa/tree/v8.0.3"
},
- "time": "2025-09-24T15:06:41+00:00"
+ "time": "2024-09-05T11:56:40+00:00"
},
{
- "name": "paragonie/random_compat",
- "version": "v9.99.100",
+ "name": "pragmarx/random",
+ "version": "v0.2.2",
"source": {
"type": "git",
- "url": "https://github.com/paragonie/random_compat.git",
- "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
+ "url": "https://github.com/antonioribeiro/random.git",
+ "reference": "daf08a189c5d2d40d1a827db46364d3a741a51b7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
- "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
+ "url": "https://api.github.com/repos/antonioribeiro/random/zipball/daf08a189c5d2d40d1a827db46364d3a741a51b7",
+ "reference": "daf08a189c5d2d40d1a827db46364d3a741a51b7",
"shasum": ""
},
"require": {
- "php": ">= 7"
+ "php": ">=7.0"
},
"require-dev": {
- "phpunit/phpunit": "4.*|5.*",
- "vimeo/psalm": "^1"
+ "fzaninotto/faker": "~1.7",
+ "phpunit/phpunit": "~6.4",
+ "pragmarx/trivia": "~0.1",
+ "squizlabs/php_codesniffer": "^2.3"
},
"suggest": {
- "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ "fzaninotto/faker": "Allows you to get dozens of randomized types",
+ "pragmarx/trivia": "For the trivia database"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PragmaRX\\Random\\": "src"
+ }
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
- "name": "Paragon Initiative Enterprises",
- "email": "security@paragonie.com",
- "homepage": "https://paragonie.com"
+ "name": "Antonio Carlos Ribeiro",
+ "email": "acr@antoniocarlosribeiro.com",
+ "homepage": "https://antoniocarlosribeiro.com",
+ "role": "Developer"
}
],
- "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "description": "Create random chars, numbers, strings",
+ "homepage": "https://github.com/antonioribeiro/random",
"keywords": [
- "csprng",
- "polyfill",
- "pseudorandom",
- "random"
+ "Randomize",
+ "faker",
+ "pragmarx",
+ "random",
+ "random number",
+ "random pattern",
+ "random string"
],
"support": {
- "email": "info@paragonie.com",
- "issues": "https://github.com/paragonie/random_compat/issues",
- "source": "https://github.com/paragonie/random_compat"
+ "issues": "https://github.com/antonioribeiro/random/issues",
+ "source": "https://github.com/antonioribeiro/random/tree/master"
},
- "time": "2020-10-15T08:29:30+00:00"
+ "time": "2017-11-21T05:26:22+00:00"
},
{
- "name": "phpdocumentor/reflection-common",
- "version": "2.2.0",
+ "name": "pragmarx/recovery",
+ "version": "v0.2.1",
"source": {
"type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
+ "url": "https://github.com/antonioribeiro/recovery.git",
+ "reference": "b5ce4082f059afac6761714a84497816f45271cc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "url": "https://api.github.com/repos/antonioribeiro/recovery/zipball/b5ce4082f059afac6761714a84497816f45271cc",
+ "reference": "b5ce4082f059afac6761714a84497816f45271cc",
"shasum": ""
},
"require": {
- "php": "^7.2 || ^8.0"
+ "php": ">=7.0",
+ "pragmarx/random": "~0.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": ">=5.4.3",
+ "squizlabs/php_codesniffer": "^2.3",
+ "tightenco/collect": "^5.0"
+ },
+ "suggest": {
+ "tightenco/collect": "Allows to generate recovery codes as collections"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-2.x": "2.x-dev"
+ "dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": "src/"
+ "PragmaRX\\Recovery\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2473,66 +4562,52 @@
],
"authors": [
{
- "name": "Jaap van Otterdijk",
- "email": "opensource@ijaap.nl"
+ "name": "Antonio Carlos Ribeiro",
+ "email": "acr@antoniocarlosribeiro.com",
+ "homepage": "https://antoniocarlosribeiro.com",
+ "role": "Developer"
}
],
- "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
- "homepage": "http://www.phpdoc.org",
+ "description": "Create recovery codes for two factor auth",
+ "homepage": "https://github.com/antonioribeiro/recovery",
"keywords": [
- "FQSEN",
- "phpDocumentor",
- "phpdoc",
- "reflection",
- "static analysis"
+ "2fa",
+ "account recovery",
+ "auth",
+ "backup codes",
+ "google2fa",
+ "pragmarx",
+ "recovery",
+ "recovery codes",
+ "two factor auth"
],
"support": {
- "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
- "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
+ "issues": "https://github.com/antonioribeiro/recovery/issues",
+ "source": "https://github.com/antonioribeiro/recovery/tree/v0.2.1"
},
- "time": "2020-06-27T09:03:43+00:00"
+ "time": "2021-08-15T12:26:51+00:00"
},
{
- "name": "phpdocumentor/reflection-docblock",
- "version": "5.6.3",
+ "name": "psr/clock",
+ "version": "1.0.0",
"source": {
"type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9"
+ "url": "https://github.com/php-fig/clock.git",
+ "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94f8051919d1b0369a6bcc7931d679a511c03fe9",
- "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9",
+ "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d",
+ "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d",
"shasum": ""
},
"require": {
- "doctrine/deprecations": "^1.1",
- "ext-filter": "*",
- "php": "^7.4 || ^8.0",
- "phpdocumentor/reflection-common": "^2.2",
- "phpdocumentor/type-resolver": "^1.7",
- "phpstan/phpdoc-parser": "^1.7|^2.0",
- "webmozart/assert": "^1.9.1"
- },
- "require-dev": {
- "mockery/mockery": "~1.3.5 || ~1.6.0",
- "phpstan/extension-installer": "^1.1",
- "phpstan/phpstan": "^1.8",
- "phpstan/phpstan-mockery": "^1.1",
- "phpstan/phpstan-webmozart-assert": "^1.2",
- "phpunit/phpunit": "^9.5",
- "psalm/phar": "^5.26"
+ "php": "^7.0 || ^8.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": "src"
+ "Psr\\Clock\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2541,60 +4616,51 @@
],
"authors": [
{
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- },
- {
- "name": "Jaap van Otterdijk",
- "email": "opensource@ijaap.nl"
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "description": "Common interface for reading the clock.",
+ "homepage": "https://github.com/php-fig/clock",
+ "keywords": [
+ "clock",
+ "now",
+ "psr",
+ "psr-20",
+ "time"
+ ],
"support": {
- "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
- "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.3"
+ "issues": "https://github.com/php-fig/clock/issues",
+ "source": "https://github.com/php-fig/clock/tree/1.0.0"
},
- "time": "2025-08-01T19:43:32+00:00"
+ "time": "2022-11-25T14:36:26+00:00"
},
{
- "name": "phpdocumentor/type-resolver",
- "version": "1.10.0",
+ "name": "psr/container",
+ "version": "2.0.2",
"source": {
"type": "git",
- "url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a"
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a",
- "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
"shasum": ""
},
"require": {
- "doctrine/deprecations": "^1.0",
- "php": "^7.3 || ^8.0",
- "phpdocumentor/reflection-common": "^2.0",
- "phpstan/phpdoc-parser": "^1.18|^2.0"
- },
- "require-dev": {
- "ext-tokenizer": "*",
- "phpbench/phpbench": "^1.2",
- "phpstan/extension-installer": "^1.1",
- "phpstan/phpstan": "^1.8",
- "phpstan/phpstan-phpunit": "^1.1",
- "phpunit/phpunit": "^9.5",
- "rector/rector": "^0.13.9",
- "vimeo/psalm": "^4.25"
+ "php": ">=7.4.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-1.x": "1.x-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": "src"
+ "Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2603,99 +4669,102 @@
],
"authors": [
{
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+ "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/phpDocumentor/TypeResolver/issues",
- "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0"
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/2.0.2"
},
- "time": "2024-11-09T15:12:26+00:00"
+ "time": "2021-11-05T16:47:00+00:00"
},
{
- "name": "phpstan/phpdoc-parser",
- "version": "2.3.0",
+ "name": "psr/event-dispatcher",
+ "version": "1.0.0",
"source": {
"type": "git",
- "url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495"
+ "url": "https://github.com/php-fig/event-dispatcher.git",
+ "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495",
- "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495",
+ "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
+ "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
"shasum": ""
},
"require": {
- "php": "^7.4 || ^8.0"
- },
- "require-dev": {
- "doctrine/annotations": "^2.0",
- "nikic/php-parser": "^5.3.0",
- "php-parallel-lint/php-parallel-lint": "^1.2",
- "phpstan/extension-installer": "^1.0",
- "phpstan/phpstan": "^2.0",
- "phpstan/phpstan-phpunit": "^2.0",
- "phpstan/phpstan-strict-rules": "^2.0",
- "phpunit/phpunit": "^9.6",
- "symfony/process": "^5.2"
+ "php": ">=7.2.0"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
- "PHPStan\\PhpDocParser\\": [
- "src/"
- ]
+ "Psr\\EventDispatcher\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "PHPDoc parser with support for nullable, intersection and generic types",
+ "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/phpstan/phpdoc-parser/issues",
- "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0"
+ "issues": "https://github.com/php-fig/event-dispatcher/issues",
+ "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
},
- "time": "2025-08-30T15:50:23+00:00"
+ "time": "2019-01-08T18:20:26+00:00"
},
{
- "name": "pixelandtonic/imagine",
- "version": "1.3.3.1",
+ "name": "psr/http-client",
+ "version": "1.0.3",
"source": {
"type": "git",
- "url": "https://github.com/pixelandtonic/Imagine.git",
- "reference": "4d9bb596ff60504e37ccf9103c0bb705dba7fec6"
+ "url": "https://github.com/php-fig/http-client.git",
+ "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/pixelandtonic/Imagine/zipball/4d9bb596ff60504e37ccf9103c0bb705dba7fec6",
- "reference": "4d9bb596ff60504e37ccf9103c0bb705dba7fec6",
+ "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
+ "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
"shasum": ""
},
"require": {
- "php": ">=5.5"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.4 || ^9.3"
- },
- "suggest": {
- "ext-exif": "to read EXIF metadata",
- "ext-gd": "to use the GD implementation",
- "ext-gmagick": "to use the Gmagick implementation",
- "ext-imagick": "to use the Imagick implementation"
+ "php": "^7.0 || ^8.0",
+ "psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-develop": "1.x-dev"
+ "dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
- "Imagine\\": "src/"
+ "Psr\\Http\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2704,50 +4773,50 @@
],
"authors": [
{
- "name": "Bulat Shakirzyanov",
- "email": "mallluhuct@gmail.com",
- "homepage": "http://avalanche123.com"
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "description": "Image processing for PHP 5.3",
- "homepage": "http://imagine.readthedocs.org/",
+ "description": "Common interface for HTTP clients",
+ "homepage": "https://github.com/php-fig/http-client",
"keywords": [
- "drawing",
- "graphics",
- "image manipulation",
- "image processing"
+ "http",
+ "http-client",
+ "psr",
+ "psr-18"
],
"support": {
- "source": "https://github.com/pixelandtonic/Imagine/tree/1.3.3.1"
+ "source": "https://github.com/php-fig/http-client"
},
- "time": "2023-01-03T19:18:06+00:00"
+ "time": "2023-09-23T14:17:50+00:00"
},
{
- "name": "pragmarx/google2fa",
- "version": "v8.0.3",
+ "name": "psr/http-factory",
+ "version": "1.1.0",
"source": {
"type": "git",
- "url": "https://github.com/antonioribeiro/google2fa.git",
- "reference": "6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad"
+ "url": "https://github.com/php-fig/http-factory.git",
+ "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad",
- "reference": "6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad",
+ "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
+ "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
"shasum": ""
},
"require": {
- "paragonie/constant_time_encoding": "^1.0|^2.0|^3.0",
- "php": "^7.1|^8.0"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.9",
- "phpunit/phpunit": "^7.5.15|^8.5|^9.0"
+ "php": ">=7.1",
+ "psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
- "PragmaRX\\Google2FA\\": "src/"
+ "Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2756,60 +4825,52 @@
],
"authors": [
{
- "name": "Antonio Carlos Ribeiro",
- "email": "acr@antoniocarlosribeiro.com",
- "role": "Creator & Designer"
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "description": "A One Time Password Authentication package, compatible with Google Authenticator.",
+ "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
"keywords": [
- "2fa",
- "Authentication",
- "Two Factor Authentication",
- "google2fa"
+ "factory",
+ "http",
+ "message",
+ "psr",
+ "psr-17",
+ "psr-7",
+ "request",
+ "response"
],
"support": {
- "issues": "https://github.com/antonioribeiro/google2fa/issues",
- "source": "https://github.com/antonioribeiro/google2fa/tree/v8.0.3"
+ "source": "https://github.com/php-fig/http-factory"
},
- "time": "2024-09-05T11:56:40+00:00"
+ "time": "2024-04-15T12:06:14+00:00"
},
{
- "name": "pragmarx/random",
- "version": "v0.2.2",
+ "name": "psr/http-message",
+ "version": "2.0",
"source": {
"type": "git",
- "url": "https://github.com/antonioribeiro/random.git",
- "reference": "daf08a189c5d2d40d1a827db46364d3a741a51b7"
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/antonioribeiro/random/zipball/daf08a189c5d2d40d1a827db46364d3a741a51b7",
- "reference": "daf08a189c5d2d40d1a827db46364d3a741a51b7",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
+ "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"shasum": ""
},
"require": {
- "php": ">=7.0"
- },
- "require-dev": {
- "fzaninotto/faker": "~1.7",
- "phpunit/phpunit": "~6.4",
- "pragmarx/trivia": "~0.1",
- "squizlabs/php_codesniffer": "^2.3"
- },
- "suggest": {
- "fzaninotto/faker": "Allows you to get dozens of randomized types",
- "pragmarx/trivia": "For the trivia database"
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
- "PragmaRX\\Random\\": "src"
+ "Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2818,64 +4879,51 @@
],
"authors": [
{
- "name": "Antonio Carlos Ribeiro",
- "email": "acr@antoniocarlosribeiro.com",
- "homepage": "https://antoniocarlosribeiro.com",
- "role": "Developer"
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "description": "Create random chars, numbers, strings",
- "homepage": "https://github.com/antonioribeiro/random",
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
"keywords": [
- "Randomize",
- "faker",
- "pragmarx",
- "random",
- "random number",
- "random pattern",
- "random string"
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
],
"support": {
- "issues": "https://github.com/antonioribeiro/random/issues",
- "source": "https://github.com/antonioribeiro/random/tree/master"
+ "source": "https://github.com/php-fig/http-message/tree/2.0"
},
- "time": "2017-11-21T05:26:22+00:00"
+ "time": "2023-04-04T09:54:51+00:00"
},
{
- "name": "pragmarx/recovery",
- "version": "v0.2.1",
+ "name": "psr/log",
+ "version": "3.0.2",
"source": {
"type": "git",
- "url": "https://github.com/antonioribeiro/recovery.git",
- "reference": "b5ce4082f059afac6761714a84497816f45271cc"
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/antonioribeiro/recovery/zipball/b5ce4082f059afac6761714a84497816f45271cc",
- "reference": "b5ce4082f059afac6761714a84497816f45271cc",
- "shasum": ""
- },
- "require": {
- "php": ">=7.0",
- "pragmarx/random": "~0.1"
- },
- "require-dev": {
- "phpunit/phpunit": ">=5.4.3",
- "squizlabs/php_codesniffer": "^2.3",
- "tightenco/collect": "^5.0"
+ "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "shasum": ""
},
- "suggest": {
- "tightenco/collect": "Allows to generate recovery codes as collections"
+ "require": {
+ "php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "3.x-dev"
}
},
"autoload": {
"psr-4": {
- "PragmaRX\\Recovery\\": "src"
+ "Psr\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2884,52 +4932,48 @@
],
"authors": [
{
- "name": "Antonio Carlos Ribeiro",
- "email": "acr@antoniocarlosribeiro.com",
- "homepage": "https://antoniocarlosribeiro.com",
- "role": "Developer"
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "description": "Create recovery codes for two factor auth",
- "homepage": "https://github.com/antonioribeiro/recovery",
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
"keywords": [
- "2fa",
- "account recovery",
- "auth",
- "backup codes",
- "google2fa",
- "pragmarx",
- "recovery",
- "recovery codes",
- "two factor auth"
+ "log",
+ "psr",
+ "psr-3"
],
"support": {
- "issues": "https://github.com/antonioribeiro/recovery/issues",
- "source": "https://github.com/antonioribeiro/recovery/tree/v0.2.1"
+ "source": "https://github.com/php-fig/log/tree/3.0.2"
},
- "time": "2021-08-15T12:26:51+00:00"
+ "time": "2024-09-11T13:17:53+00:00"
},
{
- "name": "psr/clock",
- "version": "1.0.0",
+ "name": "psr/simple-cache",
+ "version": "3.0.0",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/clock.git",
- "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d"
+ "url": "https://github.com/php-fig/simple-cache.git",
+ "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d",
- "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d",
+ "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865",
+ "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865",
"shasum": ""
},
"require": {
- "php": "^7.0 || ^8.0"
+ "php": ">=8.0.0"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
- "Psr\\Clock\\": "src/"
+ "Psr\\SimpleCache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2942,48 +4986,45 @@
"homepage": "https://www.php-fig.org/"
}
],
- "description": "Common interface for reading the clock.",
- "homepage": "https://github.com/php-fig/clock",
+ "description": "Common interfaces for simple caching",
"keywords": [
- "clock",
- "now",
+ "cache",
+ "caching",
"psr",
- "psr-20",
- "time"
+ "psr-16",
+ "simple-cache"
],
"support": {
- "issues": "https://github.com/php-fig/clock/issues",
- "source": "https://github.com/php-fig/clock/tree/1.0.0"
+ "source": "https://github.com/php-fig/simple-cache/tree/3.0.0"
},
- "time": "2022-11-25T14:36:26+00:00"
+ "time": "2021-10-29T13:26:27+00:00"
},
{
- "name": "psr/container",
- "version": "2.0.2",
+ "name": "ralouphie/getallheaders",
+ "version": "3.0.3",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/container.git",
- "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
+ "url": "https://github.com/ralouphie/getallheaders.git",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
- "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
- "php": ">=7.4.0"
+ "php": ">=5.6"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^5 || ^6.5"
},
+ "type": "library",
"autoload": {
- "psr-4": {
- "Psr\\Container\\": "src/"
- }
+ "files": [
+ "src/getallheaders.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2991,1082 +5032,1095 @@
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
}
],
- "description": "Common Container Interface (PHP FIG PSR-11)",
- "homepage": "https://github.com/php-fig/container",
- "keywords": [
- "PSR-11",
- "container",
- "container-interface",
- "container-interop",
- "psr"
- ],
+ "description": "A polyfill for getallheaders.",
"support": {
- "issues": "https://github.com/php-fig/container/issues",
- "source": "https://github.com/php-fig/container/tree/2.0.2"
+ "issues": "https://github.com/ralouphie/getallheaders/issues",
+ "source": "https://github.com/ralouphie/getallheaders/tree/develop"
},
- "time": "2021-11-05T16:47:00+00:00"
+ "time": "2019-03-08T08:55:37+00:00"
},
{
- "name": "psr/event-dispatcher",
- "version": "1.0.0",
+ "name": "samdark/yii2-psr-log-target",
+ "version": "1.1.4",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/event-dispatcher.git",
- "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
+ "url": "https://github.com/samdark/yii2-psr-log-target.git",
+ "reference": "5f14f21d5ee4294fe9eb3e723ec8a3908ca082ea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
- "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
+ "url": "https://api.github.com/repos/samdark/yii2-psr-log-target/zipball/5f14f21d5ee4294fe9eb3e723ec8a3908ca082ea",
+ "reference": "5f14f21d5ee4294fe9eb3e723ec8a3908ca082ea",
"shasum": ""
},
"require": {
- "php": ">=7.2.0"
+ "psr/log": "~1.0.2|~1.1.0|~3.0.0",
+ "yiisoft/yii2": "~2.0.0"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
+ "require-dev": {
+ "phpunit/phpunit": "~4.4|~10.4.2"
},
+ "type": "yii2-extension",
"autoload": {
"psr-4": {
- "Psr\\EventDispatcher\\": "src/"
+ "samdark\\log\\": "src",
+ "samdark\\log\\tests\\": "tests"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "name": "Alexander Makarov",
+ "email": "sam@rmcreative.ru"
}
],
- "description": "Standard interfaces for event handling.",
+ "description": "Yii 2 log target which uses PSR-3 compatible logger",
+ "homepage": "https://github.com/samdark/yii2-psr-log-target",
"keywords": [
- "events",
- "psr",
- "psr-14"
+ "extension",
+ "log",
+ "psr-3",
+ "yii"
],
"support": {
- "issues": "https://github.com/php-fig/event-dispatcher/issues",
- "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
+ "issues": "https://github.com/samdark/yii2-psr-log-target/issues",
+ "source": "https://github.com/samdark/yii2-psr-log-target"
},
- "time": "2019-01-08T18:20:26+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/samdark",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/samdark",
+ "type": "patreon"
+ }
+ ],
+ "time": "2023-11-23T14:11:29+00:00"
},
{
- "name": "psr/http-client",
- "version": "1.0.3",
+ "name": "sebastian/cli-parser",
+ "version": "3.0.2",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/http-client.git",
- "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
+ "url": "https://github.com/sebastianbergmann/cli-parser.git",
+ "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
- "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180",
+ "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180",
"shasum": ""
},
"require": {
- "php": "^7.0 || ^8.0",
- "psr/http-message": "^1.0 || ^2.0"
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-main": "3.0-dev"
}
},
"autoload": {
- "psr-4": {
- "Psr\\Http\\Client\\": "src/"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "Common interface for HTTP clients",
- "homepage": "https://github.com/php-fig/http-client",
- "keywords": [
- "http",
- "http-client",
- "psr",
- "psr-18"
- ],
+ "description": "Library for parsing CLI options",
+ "homepage": "https://github.com/sebastianbergmann/cli-parser",
"support": {
- "source": "https://github.com/php-fig/http-client"
+ "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"
},
- "time": "2023-09-23T14:17:50+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:41:36+00:00"
},
{
- "name": "psr/http-factory",
- "version": "1.1.0",
+ "name": "sebastian/code-unit",
+ "version": "3.0.3",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/http-factory.git",
- "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
+ "url": "https://github.com/sebastianbergmann/code-unit.git",
+ "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
- "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64",
+ "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64",
"shasum": ""
},
"require": {
- "php": ">=7.1",
- "psr/http-message": "^1.0 || ^2.0"
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-main": "3.0-dev"
}
},
"autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
- }
- ],
- "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
- "keywords": [
- "factory",
- "http",
- "message",
- "psr",
- "psr-17",
- "psr-7",
- "request",
- "response"
+ "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": {
- "source": "https://github.com/php-fig/http-factory"
+ "issues": "https://github.com/sebastianbergmann/code-unit/issues",
+ "security": "https://github.com/sebastianbergmann/code-unit/security/policy",
+ "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3"
},
- "time": "2024-04-15T12:06:14+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2025-03-19T07:56:08+00:00"
},
{
- "name": "psr/http-message",
- "version": "2.0",
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "4.0.1",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "183a9b2632194febd219bb9246eee421dad8d45e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
- "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e",
+ "reference": "183a9b2632194febd219bb9246eee421dad8d45e",
"shasum": ""
},
"require": {
- "php": "^7.2 || ^8.0"
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0.x-dev"
+ "dev-main": "4.0-dev"
}
},
"autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
}
],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
- "keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
- ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
"support": {
- "source": "https://github.com/php-fig/http-message/tree/2.0"
+ "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"
},
- "time": "2023-04-04T09:54:51+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:45:54+00:00"
},
{
- "name": "psr/log",
- "version": "3.0.2",
+ "name": "sebastian/comparator",
+ "version": "6.3.3",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/log.git",
- "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
- "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2c95e1e86cb8dd41beb8d502057d1081ccc8eca9",
+ "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9",
"shasum": ""
},
"require": {
- "php": ">=8.0.0"
+ "ext-dom": "*",
+ "ext-mbstring": "*",
+ "php": ">=8.2",
+ "sebastian/diff": "^6.0",
+ "sebastian/exporter": "^6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.4"
+ },
+ "suggest": {
+ "ext-bcmath": "For comparing BcMath\\Number objects"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.x-dev"
+ "dev-main": "6.3-dev"
}
},
"autoload": {
- "psr-4": {
- "Psr\\Log\\": "src"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
+ "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": "Common interface for logging libraries",
- "homepage": "https://github.com/php-fig/log",
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "https://github.com/sebastianbergmann/comparator",
"keywords": [
- "log",
- "psr",
- "psr-3"
+ "comparator",
+ "compare",
+ "equality"
],
"support": {
- "source": "https://github.com/php-fig/log/tree/3.0.2"
+ "issues": "https://github.com/sebastianbergmann/comparator/issues",
+ "security": "https://github.com/sebastianbergmann/comparator/security/policy",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.3"
},
- "time": "2024-09-11T13:17:53+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ },
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-01-24T09:26:40+00:00"
},
{
- "name": "psr/simple-cache",
- "version": "3.0.0",
+ "name": "sebastian/complexity",
+ "version": "4.0.1",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/simple-cache.git",
- "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865"
+ "url": "https://github.com/sebastianbergmann/complexity.git",
+ "reference": "ee41d384ab1906c68852636b6de493846e13e5a0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865",
- "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0",
+ "reference": "ee41d384ab1906c68852636b6de493846e13e5a0",
"shasum": ""
},
"require": {
- "php": ">=8.0.0"
+ "nikic/php-parser": "^5.0",
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0.x-dev"
+ "dev-main": "4.0-dev"
}
},
"autoload": {
- "psr-4": {
- "Psr\\SimpleCache\\": "src/"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "Common interfaces for simple caching",
- "keywords": [
- "cache",
- "caching",
- "psr",
- "psr-16",
- "simple-cache"
- ],
+ "description": "Library for calculating the complexity of PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/complexity",
"support": {
- "source": "https://github.com/php-fig/simple-cache/tree/3.0.0"
+ "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"
},
- "time": "2021-10-29T13:26:27+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:49:50+00:00"
},
{
- "name": "ralouphie/getallheaders",
- "version": "3.0.3",
+ "name": "sebastian/diff",
+ "version": "6.0.2",
"source": {
"type": "git",
- "url": "https://github.com/ralouphie/getallheaders.git",
- "reference": "120b605dfeb996808c31b6477290a714d356e822"
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
- "reference": "120b605dfeb996808c31b6477290a714d356e822",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544",
+ "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544",
"shasum": ""
},
"require": {
- "php": ">=5.6"
+ "php": ">=8.2"
},
"require-dev": {
- "php-coveralls/php-coveralls": "^2.1",
- "phpunit/phpunit": "^5 || ^6.5"
+ "phpunit/phpunit": "^11.0",
+ "symfony/process": "^4.2 || ^5"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "6.0-dev"
+ }
+ },
"autoload": {
- "files": [
- "src/getallheaders.php"
+ "classmap": [
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Ralph Khattar",
- "email": "ralph.khattar@gmail.com"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
}
],
- "description": "A polyfill for getallheaders.",
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
+ ],
"support": {
- "issues": "https://github.com/ralouphie/getallheaders/issues",
- "source": "https://github.com/ralouphie/getallheaders/tree/develop"
+ "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"
},
- "time": "2019-03-08T08:55:37+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-07-03T04:53:05+00:00"
},
{
- "name": "samdark/yii2-psr-log-target",
- "version": "1.1.4",
+ "name": "sebastian/environment",
+ "version": "7.2.1",
"source": {
"type": "git",
- "url": "https://github.com/samdark/yii2-psr-log-target.git",
- "reference": "5f14f21d5ee4294fe9eb3e723ec8a3908ca082ea"
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/samdark/yii2-psr-log-target/zipball/5f14f21d5ee4294fe9eb3e723ec8a3908ca082ea",
- "reference": "5f14f21d5ee4294fe9eb3e723ec8a3908ca082ea",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4",
+ "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4",
"shasum": ""
},
"require": {
- "psr/log": "~1.0.2|~1.1.0|~3.0.0",
- "yiisoft/yii2": "~2.0.0"
+ "php": ">=8.2"
},
"require-dev": {
- "phpunit/phpunit": "~4.4|~10.4.2"
+ "phpunit/phpunit": "^11.3"
},
- "type": "yii2-extension",
- "autoload": {
- "psr-4": {
- "samdark\\log\\": "src",
- "samdark\\log\\tests\\": "tests"
+ "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": "Alexander Makarov",
- "email": "sam@rmcreative.ru"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
}
],
- "description": "Yii 2 log target which uses PSR-3 compatible logger",
- "homepage": "https://github.com/samdark/yii2-psr-log-target",
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "https://github.com/sebastianbergmann/environment",
"keywords": [
- "extension",
- "log",
- "psr-3",
- "yii"
+ "Xdebug",
+ "environment",
+ "hhvm"
],
"support": {
- "issues": "https://github.com/samdark/yii2-psr-log-target/issues",
- "source": "https://github.com/samdark/yii2-psr-log-target"
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "security": "https://github.com/sebastianbergmann/environment/security/policy",
+ "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1"
},
"funding": [
{
- "url": "https://github.com/samdark",
+ "url": "https://github.com/sebastianbergmann",
"type": "github"
},
{
- "url": "https://www.patreon.com/samdark",
- "type": "patreon"
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/sebastian/environment",
+ "type": "tidelift"
}
],
- "time": "2023-11-23T14:11:29+00:00"
+ "time": "2025-05-21T11:55:47+00:00"
},
{
- "name": "seld/cli-prompt",
- "version": "1.0.4",
+ "name": "sebastian/exporter",
+ "version": "6.3.2",
"source": {
"type": "git",
- "url": "https://github.com/Seldaek/cli-prompt.git",
- "reference": "b8dfcf02094b8c03b40322c229493bb2884423c5"
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "70a298763b40b213ec087c51c739efcaa90bcd74"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/b8dfcf02094b8c03b40322c229493bb2884423c5",
- "reference": "b8dfcf02094b8c03b40322c229493bb2884423c5",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74",
+ "reference": "70a298763b40b213ec087c51c739efcaa90bcd74",
"shasum": ""
},
"require": {
- "php": ">=5.3"
+ "ext-mbstring": "*",
+ "php": ">=8.2",
+ "sebastian/recursion-context": "^6.0"
},
"require-dev": {
- "phpstan/phpstan": "^0.12.63"
+ "phpunit/phpunit": "^11.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.x-dev"
+ "dev-main": "6.3-dev"
}
},
"autoload": {
- "psr-4": {
- "Seld\\CliPrompt\\": "src/"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be"
+ "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": "Allows you to prompt for user input on the command line, and optionally hide the characters they type",
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "https://www.github.com/sebastianbergmann/exporter",
"keywords": [
- "cli",
- "console",
- "hidden",
- "input",
- "prompt"
+ "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.3.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ },
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter",
+ "type": "tidelift"
+ }
],
- "support": {
- "issues": "https://github.com/Seldaek/cli-prompt/issues",
- "source": "https://github.com/Seldaek/cli-prompt/tree/1.0.4"
- },
- "time": "2020-12-15T21:32:01+00:00"
+ "time": "2025-09-24T06:12:51+00:00"
},
{
- "name": "spomky-labs/cbor-php",
- "version": "3.1.1",
+ "name": "sebastian/global-state",
+ "version": "7.0.2",
"source": {
"type": "git",
- "url": "https://github.com/Spomky-Labs/cbor-php.git",
- "reference": "5404f3e21cbe72f5cf612aa23db2b922fd2f43bf"
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "3be331570a721f9a4b5917f4209773de17f747d7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Spomky-Labs/cbor-php/zipball/5404f3e21cbe72f5cf612aa23db2b922fd2f43bf",
- "reference": "5404f3e21cbe72f5cf612aa23db2b922fd2f43bf",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7",
+ "reference": "3be331570a721f9a4b5917f4209773de17f747d7",
"shasum": ""
},
"require": {
- "brick/math": "^0.9|^0.10|^0.11|^0.12|^0.13",
- "ext-mbstring": "*",
- "php": ">=8.0"
+ "php": ">=8.2",
+ "sebastian/object-reflector": "^4.0",
+ "sebastian/recursion-context": "^6.0"
},
"require-dev": {
- "deptrac/deptrac": "^3.0",
- "ekino/phpstan-banned-code": "^1.0|^2.0|^3.0",
- "ext-json": "*",
- "infection/infection": "^0.29",
- "php-parallel-lint/php-parallel-lint": "^1.3",
- "phpstan/extension-installer": "^1.1",
- "phpstan/phpstan": "^1.0|^2.0",
- "phpstan/phpstan-beberlei-assert": "^1.0|^2.0",
- "phpstan/phpstan-deprecation-rules": "^1.0|^2.0",
- "phpstan/phpstan-phpunit": "^1.0|^2.0",
- "phpstan/phpstan-strict-rules": "^1.0|^2.0",
- "phpunit/phpunit": "^10.1|^11.0|^12.0",
- "rector/rector": "^1.0|^2.0",
- "roave/security-advisories": "dev-latest",
- "symfony/var-dumper": "^6.0|^7.0",
- "symplify/easy-coding-standard": "^12.0"
- },
- "suggest": {
- "ext-bcmath": "GMP or BCMath extensions will drastically improve the library performance. BCMath extension needed to handle the Big Float and Decimal Fraction Tags",
- "ext-gmp": "GMP or BCMath extensions will drastically improve the library performance"
+ "ext-dom": "*",
+ "phpunit/phpunit": "^11.0"
},
"type": "library",
- "autoload": {
- "psr-4": {
- "CBOR\\": "src/"
+ "extra": {
+ "branch-alias": {
+ "dev-main": "7.0-dev"
}
},
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Florent Morselli",
- "homepage": "https://github.com/Spomky"
- },
- {
- "name": "All contributors",
- "homepage": "https://github.com/Spomky-Labs/cbor-php/contributors"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
}
],
- "description": "CBOR Encoder/Decoder for PHP",
+ "description": "Snapshotting of global state",
+ "homepage": "https://www.github.com/sebastianbergmann/global-state",
"keywords": [
- "Concise Binary Object Representation",
- "RFC7049",
- "cbor"
+ "global state"
],
"support": {
- "issues": "https://github.com/Spomky-Labs/cbor-php/issues",
- "source": "https://github.com/Spomky-Labs/cbor-php/tree/3.1.1"
+ "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/Spomky",
+ "url": "https://github.com/sebastianbergmann",
"type": "github"
- },
- {
- "url": "https://www.patreon.com/FlorentMorselli",
- "type": "patreon"
}
],
- "time": "2025-06-13T11:57:55+00:00"
+ "time": "2024-07-03T04:57:36+00:00"
},
{
- "name": "spomky-labs/pki-framework",
- "version": "1.4.0",
+ "name": "sebastian/lines-of-code",
+ "version": "3.0.1",
"source": {
"type": "git",
- "url": "https://github.com/Spomky-Labs/pki-framework.git",
- "reference": "bf6f55a9d9eb25b7781640221cb54f5c727850d7"
+ "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+ "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Spomky-Labs/pki-framework/zipball/bf6f55a9d9eb25b7781640221cb54f5c727850d7",
- "reference": "bf6f55a9d9eb25b7781640221cb54f5c727850d7",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a",
+ "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a",
"shasum": ""
},
"require": {
- "brick/math": "^0.10|^0.11|^0.12|^0.13|^0.14",
- "ext-mbstring": "*",
- "php": ">=8.1"
+ "nikic/php-parser": "^5.0",
+ "php": ">=8.2"
},
"require-dev": {
- "ekino/phpstan-banned-code": "^1.0|^2.0|^3.0",
- "ext-gmp": "*",
- "ext-openssl": "*",
- "infection/infection": "^0.28|^0.29|^0.31",
- "php-parallel-lint/php-parallel-lint": "^1.3",
- "phpstan/extension-installer": "^1.3|^2.0",
- "phpstan/phpstan": "^1.8|^2.0",
- "phpstan/phpstan-deprecation-rules": "^1.0|^2.0",
- "phpstan/phpstan-phpunit": "^1.1|^2.0",
- "phpstan/phpstan-strict-rules": "^1.3|^2.0",
- "phpunit/phpunit": "^10.1|^11.0|^12.0",
- "rector/rector": "^1.0|^2.0",
- "roave/security-advisories": "dev-latest",
- "symfony/string": "^6.4|^7.0|^8.0",
- "symfony/var-dumper": "^6.4|^7.0|^8.0",
- "symplify/easy-coding-standard": "^12.0"
- },
- "suggest": {
- "ext-bcmath": "For better performance (or GMP)",
- "ext-gmp": "For better performance (or BCMath)",
- "ext-openssl": "For OpenSSL based cyphering"
+ "phpunit/phpunit": "^11.0"
},
"type": "library",
- "autoload": {
- "psr-4": {
- "SpomkyLabs\\Pki\\": "src/"
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.0-dev"
}
},
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Joni Eskelinen",
- "email": "jonieske@gmail.com",
- "role": "Original developer"
- },
- {
- "name": "Florent Morselli",
- "email": "florent.morselli@spomky-labs.com",
- "role": "Spomky-Labs PKI Framework developer"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "A PHP framework for managing Public Key Infrastructures. It comprises X.509 public key certificates, attribute certificates, certification requests and certification path validation.",
- "homepage": "https://github.com/spomky-labs/pki-framework",
- "keywords": [
- "DER",
- "Private Key",
- "ac",
- "algorithm identifier",
- "asn.1",
- "asn1",
- "attribute certificate",
- "certificate",
- "certification request",
- "cryptography",
- "csr",
- "decrypt",
- "ec",
- "encrypt",
- "pem",
- "pkcs",
- "public key",
- "rsa",
- "sign",
- "signature",
- "verify",
- "x.509",
- "x.690",
- "x509",
- "x690"
- ],
+ "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/Spomky-Labs/pki-framework/issues",
- "source": "https://github.com/Spomky-Labs/pki-framework/tree/1.4.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": [
{
- "url": "https://github.com/Spomky",
+ "url": "https://github.com/sebastianbergmann",
"type": "github"
- },
- {
- "url": "https://www.patreon.com/FlorentMorselli",
- "type": "patreon"
}
],
- "time": "2025-10-22T08:24:34+00:00"
+ "time": "2024-07-03T04:58:38+00:00"
},
{
- "name": "symfony/css-selector",
- "version": "v7.3.0",
+ "name": "sebastian/object-enumerator",
+ "version": "6.0.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/css-selector.git",
- "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2"
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "f5b498e631a74204185071eb41f33f38d64608aa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2",
- "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2",
+ "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": {
+ "phpunit/phpunit": "^11.0"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "6.0-dev"
+ }
+ },
"autoload": {
- "psr-4": {
- "Symfony\\Component\\CssSelector\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Jean-François Simon",
- "email": "jeanfrancois.simon@sensiolabs.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
}
],
- "description": "Converts CSS selectors to XPath expressions",
- "homepage": "https://symfony.com",
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
"support": {
- "source": "https://github.com/symfony/css-selector/tree/v7.3.0"
+ "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": [
{
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
+ "url": "https://github.com/sebastianbergmann",
"type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
}
],
- "time": "2024-09-25T14:21:43+00:00"
+ "time": "2024-07-03T05:00:13+00:00"
},
{
- "name": "symfony/deprecation-contracts",
- "version": "v3.6.0",
+ "name": "sebastian/object-reflector",
+ "version": "4.0.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62"
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62",
- "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9",
+ "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9",
"shasum": ""
},
"require": {
- "php": ">=8.1"
+ "php": ">=8.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.0"
},
"type": "library",
"extra": {
- "thanks": {
- "url": "https://github.com/symfony/contracts",
- "name": "symfony/contracts"
- },
"branch-alias": {
- "dev-main": "3.6-dev"
+ "dev-main": "4.0-dev"
}
},
"autoload": {
- "files": [
- "function.php"
+ "classmap": [
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
}
],
- "description": "A generic function and convention to trigger deprecation notices",
- "homepage": "https://symfony.com",
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0"
+ "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+ "security": "https://github.com/sebastianbergmann/object-reflector/security/policy",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1"
},
"funding": [
{
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
+ "url": "https://github.com/sebastianbergmann",
"type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
}
],
- "time": "2024-09-25T14:21:43+00:00"
+ "time": "2024-07-03T05:01:32+00:00"
},
{
- "name": "symfony/dom-crawler",
- "version": "v7.3.3",
+ "name": "sebastian/recursion-context",
+ "version": "6.0.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/dom-crawler.git",
- "reference": "efa076ea0eeff504383ff0dcf827ea5ce15690ba"
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/efa076ea0eeff504383ff0dcf827ea5ce15690ba",
- "reference": "efa076ea0eeff504383ff0dcf827ea5ce15690ba",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc",
+ "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc",
"shasum": ""
},
"require": {
- "masterminds/html5": "^2.6",
- "php": ">=8.2",
- "symfony/polyfill-ctype": "~1.8",
- "symfony/polyfill-mbstring": "~1.0"
+ "php": ">=8.2"
},
"require-dev": {
- "symfony/css-selector": "^6.4|^7.0"
+ "phpunit/phpunit": "^11.3"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "6.0-dev"
+ }
+ },
"autoload": {
- "psr-4": {
- "Symfony\\Component\\DomCrawler\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
},
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
}
],
- "description": "Eases DOM navigation for HTML and XML documents",
- "homepage": "https://symfony.com",
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "https://github.com/sebastianbergmann/recursion-context",
"support": {
- "source": "https://github.com/symfony/dom-crawler/tree/v7.3.3"
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "security": "https://github.com/sebastianbergmann/recursion-context/security/policy",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3"
},
"funding": [
{
- "url": "https://symfony.com/sponsor",
- "type": "custom"
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
},
{
- "url": "https://github.com/fabpot",
- "type": "github"
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
},
{
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
},
{
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
"type": "tidelift"
}
],
- "time": "2025-08-06T20:13:54+00:00"
+ "time": "2025-08-13T04:42:22+00:00"
},
{
- "name": "symfony/event-dispatcher",
- "version": "v7.3.3",
+ "name": "sebastian/type",
+ "version": "5.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191"
+ "url": "https://github.com/sebastianbergmann/type.git",
+ "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191",
- "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449",
+ "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449",
"shasum": ""
},
"require": {
- "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"
+ "php": ">=8.2"
},
"require-dev": {
- "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"
+ "phpunit/phpunit": "^11.3"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "5.1-dev"
+ }
+ },
"autoload": {
- "psr-4": {
- "Symfony\\Component\\EventDispatcher\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
- "homepage": "https://symfony.com",
+ "description": "Collection of value objects that represent the types of the PHP type system",
+ "homepage": "https://github.com/sebastianbergmann/type",
"support": {
- "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3"
+ "issues": "https://github.com/sebastianbergmann/type/issues",
+ "security": "https://github.com/sebastianbergmann/type/security/policy",
+ "source": "https://github.com/sebastianbergmann/type/tree/5.1.3"
},
"funding": [
{
- "url": "https://symfony.com/sponsor",
- "type": "custom"
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
},
{
- "url": "https://github.com/fabpot",
- "type": "github"
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
},
{
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
},
{
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "url": "https://tidelift.com/funding/github/packagist/sebastian/type",
"type": "tidelift"
}
],
- "time": "2025-08-13T11:49:31+00:00"
+ "time": "2025-08-09T06:55:48+00:00"
},
{
- "name": "symfony/event-dispatcher-contracts",
- "version": "v3.6.0",
+ "name": "sebastian/version",
+ "version": "5.0.2",
"source": {
"type": "git",
- "url": "https://github.com/symfony/event-dispatcher-contracts.git",
- "reference": "59eb412e93815df44f05f342958efa9f46b1e586"
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586",
- "reference": "59eb412e93815df44f05f342958efa9f46b1e586",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874",
+ "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874",
"shasum": ""
},
"require": {
- "php": ">=8.1",
- "psr/event-dispatcher": "^1"
+ "php": ">=8.2"
},
"type": "library",
"extra": {
- "thanks": {
- "url": "https://github.com/symfony/contracts",
- "name": "symfony/contracts"
- },
"branch-alias": {
- "dev-main": "3.6-dev"
+ "dev-main": "5.0-dev"
}
},
"autoload": {
- "psr-4": {
- "Symfony\\Contracts\\EventDispatcher\\": ""
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "Generic abstractions related to dispatching event",
- "homepage": "https://symfony.com",
- "keywords": [
- "abstractions",
- "contracts",
- "decoupling",
- "interfaces",
- "interoperability",
- "standards"
- ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
"support": {
- "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0"
+ "issues": "https://github.com/sebastianbergmann/version/issues",
+ "security": "https://github.com/sebastianbergmann/version/security/policy",
+ "source": "https://github.com/sebastianbergmann/version/tree/5.0.2"
},
"funding": [
{
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
+ "url": "https://github.com/sebastianbergmann",
"type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
}
],
- "time": "2024-09-25T14:21:43+00:00"
+ "time": "2024-10-09T05:16:32+00:00"
},
{
- "name": "symfony/filesystem",
- "version": "v6.4.24",
+ "name": "seld/cli-prompt",
+ "version": "1.0.4",
"source": {
"type": "git",
- "url": "https://github.com/symfony/filesystem.git",
- "reference": "75ae2edb7cdcc0c53766c30b0a2512b8df574bd8"
+ "url": "https://github.com/Seldaek/cli-prompt.git",
+ "reference": "b8dfcf02094b8c03b40322c229493bb2884423c5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/75ae2edb7cdcc0c53766c30b0a2512b8df574bd8",
- "reference": "75ae2edb7cdcc0c53766c30b0a2512b8df574bd8",
+ "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/b8dfcf02094b8c03b40322c229493bb2884423c5",
+ "reference": "b8dfcf02094b8c03b40322c229493bb2884423c5",
"shasum": ""
},
"require": {
- "php": ">=8.1",
- "symfony/polyfill-ctype": "~1.8",
- "symfony/polyfill-mbstring": "~1.8"
+ "php": ">=5.3"
},
"require-dev": {
- "symfony/process": "^5.4|^6.4|^7.0"
+ "phpstan/phpstan": "^0.12.63"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
- "Symfony\\Component\\Filesystem\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Seld\\CliPrompt\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -4074,96 +6128,58 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be"
}
],
- "description": "Provides basic utilities for the filesystem",
- "homepage": "https://symfony.com",
+ "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type",
+ "keywords": [
+ "cli",
+ "console",
+ "hidden",
+ "input",
+ "prompt"
+ ],
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v6.4.24"
+ "issues": "https://github.com/Seldaek/cli-prompt/issues",
+ "source": "https://github.com/Seldaek/cli-prompt/tree/1.0.4"
},
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-07-10T08:14:14+00:00"
+ "time": "2020-12-15T21:32:01+00:00"
},
{
- "name": "symfony/http-client",
- "version": "v7.3.4",
+ "name": "spomky-labs/cbor-php",
+ "version": "3.2.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/http-client.git",
- "reference": "4b62871a01c49457cf2a8e560af7ee8a94b87a62"
+ "url": "https://github.com/Spomky-Labs/cbor-php.git",
+ "reference": "dd6eb84e6d92f7b8bd0da56b4b4dd7235aed0c32"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-client/zipball/4b62871a01c49457cf2a8e560af7ee8a94b87a62",
- "reference": "4b62871a01c49457cf2a8e560af7ee8a94b87a62",
+ "url": "https://api.github.com/repos/Spomky-Labs/cbor-php/zipball/dd6eb84e6d92f7b8bd0da56b4b4dd7235aed0c32",
+ "reference": "dd6eb84e6d92f7b8bd0da56b4b4dd7235aed0c32",
"shasum": ""
},
"require": {
- "php": ">=8.2",
- "psr/log": "^1|^2|^3",
- "symfony/deprecation-contracts": "^2.5|^3",
- "symfony/http-client-contracts": "~3.4.4|^3.5.2",
- "symfony/polyfill-php83": "^1.29",
- "symfony/service-contracts": "^2.5|^3"
- },
- "conflict": {
- "amphp/amp": "<2.5",
- "amphp/socket": "<1.1",
- "php-http/discovery": "<1.15",
- "symfony/http-foundation": "<6.4"
- },
- "provide": {
- "php-http/async-client-implementation": "*",
- "php-http/client-implementation": "*",
- "psr/http-client-implementation": "1.0",
- "symfony/http-client-implementation": "3.0"
+ "brick/math": "^0.9|^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17",
+ "ext-mbstring": "*",
+ "php": ">=8.0"
},
"require-dev": {
- "amphp/http-client": "^4.2.1|^5.0",
- "amphp/http-tunnel": "^1.0|^2.0",
- "guzzlehttp/promises": "^1.4|^2.0",
- "nyholm/psr7": "^1.0",
- "php-http/httplug": "^1.0|^2.0",
- "psr/http-client": "^1.0",
- "symfony/amphp-http-client-meta": "^1.0|^2.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/rate-limiter": "^6.4|^7.0",
- "symfony/stopwatch": "^6.4|^7.0"
+ "ext-json": "*",
+ "roave/security-advisories": "dev-latest",
+ "symfony/error-handler": "^6.4|^7.1|^8.0",
+ "symfony/var-dumper": "^6.4|^7.1|^8.0"
+ },
+ "suggest": {
+ "ext-bcmath": "GMP or BCMath extensions will drastically improve the library performance. BCMath extension needed to handle the Big Float and Decimal Fraction Tags",
+ "ext-gmp": "GMP or BCMath extensions will drastically improve the library performance"
},
"type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Component\\HttpClient\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "CBOR\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -4171,76 +6187,84 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Florent Morselli",
+ "homepage": "https://github.com/Spomky"
},
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "All contributors",
+ "homepage": "https://github.com/Spomky-Labs/cbor-php/contributors"
}
],
- "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
- "homepage": "https://symfony.com",
+ "description": "CBOR Encoder/Decoder for PHP",
"keywords": [
- "http"
+ "Concise Binary Object Representation",
+ "RFC7049",
+ "cbor"
],
"support": {
- "source": "https://github.com/symfony/http-client/tree/v7.3.4"
+ "issues": "https://github.com/Spomky-Labs/cbor-php/issues",
+ "source": "https://github.com/Spomky-Labs/cbor-php/tree/3.2.3"
},
"funding": [
{
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
+ "url": "https://github.com/Spomky",
"type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
+ "url": "https://www.patreon.com/FlorentMorselli",
+ "type": "patreon"
}
],
- "time": "2025-09-11T10:12:26+00:00"
+ "time": "2026-04-01T12:15:20+00:00"
},
{
- "name": "symfony/http-client-contracts",
- "version": "v3.6.0",
+ "name": "spomky-labs/pki-framework",
+ "version": "1.4.2",
"source": {
"type": "git",
- "url": "https://github.com/symfony/http-client-contracts.git",
- "reference": "75d7043853a42837e68111812f4d964b01e5101c"
+ "url": "https://github.com/Spomky-Labs/pki-framework.git",
+ "reference": "aa576cbd07128075bef97ac2f8af9854e67513d8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/75d7043853a42837e68111812f4d964b01e5101c",
- "reference": "75d7043853a42837e68111812f4d964b01e5101c",
+ "url": "https://api.github.com/repos/Spomky-Labs/pki-framework/zipball/aa576cbd07128075bef97ac2f8af9854e67513d8",
+ "reference": "aa576cbd07128075bef97ac2f8af9854e67513d8",
"shasum": ""
},
"require": {
- "php": ">=8.1"
+ "brick/math": "^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17",
+ "ext-mbstring": "*",
+ "php": ">=8.1",
+ "psr/clock": "^1.0"
},
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/contracts",
- "name": "symfony/contracts"
- },
- "branch-alias": {
- "dev-main": "3.6-dev"
- }
+ "require-dev": {
+ "ekino/phpstan-banned-code": "^1.0|^2.0|^3.0",
+ "ext-gmp": "*",
+ "ext-openssl": "*",
+ "infection/infection": "^0.28|^0.29|^0.31|^0.32",
+ "php-parallel-lint/php-parallel-lint": "^1.3",
+ "phpstan/extension-installer": "^1.3|^2.0",
+ "phpstan/phpstan": "^1.8|^2.0",
+ "phpstan/phpstan-deprecation-rules": "^1.0|^2.0",
+ "phpstan/phpstan-phpunit": "^1.1|^2.0",
+ "phpstan/phpstan-strict-rules": "^1.3|^2.0",
+ "phpunit/phpunit": "^10.1|^11.0|^12.0|^13.0",
+ "rector/rector": "^1.0|^2.0",
+ "roave/security-advisories": "dev-latest",
+ "symfony/string": "^6.4|^7.0|^8.0",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0",
+ "symplify/easy-coding-standard": "^12.0|^13.0"
+ },
+ "suggest": {
+ "ext-bcmath": "For better performance (or GMP)",
+ "ext-gmp": "For better performance (or BCMath)",
+ "ext-openssl": "For OpenSSL based cyphering"
},
+ "type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Contracts\\HttpClient\\": ""
- },
- "exclude-from-classmap": [
- "/Test/"
- ]
+ "SpomkyLabs\\Pki\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -4248,167 +6272,142 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Joni Eskelinen",
+ "email": "jonieske@gmail.com",
+ "role": "Original developer"
},
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Florent Morselli",
+ "email": "florent.morselli@spomky-labs.com",
+ "role": "Spomky-Labs PKI Framework developer"
}
],
- "description": "Generic abstractions related to HTTP clients",
- "homepage": "https://symfony.com",
+ "description": "A PHP framework for managing Public Key Infrastructures. It comprises X.509 public key certificates, attribute certificates, certification requests and certification path validation.",
+ "homepage": "https://github.com/spomky-labs/pki-framework",
"keywords": [
- "abstractions",
- "contracts",
- "decoupling",
- "interfaces",
- "interoperability",
- "standards"
+ "DER",
+ "Private Key",
+ "ac",
+ "algorithm identifier",
+ "asn.1",
+ "asn1",
+ "attribute certificate",
+ "certificate",
+ "certification request",
+ "cryptography",
+ "csr",
+ "decrypt",
+ "ec",
+ "encrypt",
+ "pem",
+ "pkcs",
+ "public key",
+ "rsa",
+ "sign",
+ "signature",
+ "verify",
+ "x.509",
+ "x.690",
+ "x509",
+ "x690"
],
"support": {
- "source": "https://github.com/symfony/http-client-contracts/tree/v3.6.0"
+ "issues": "https://github.com/Spomky-Labs/pki-framework/issues",
+ "source": "https://github.com/Spomky-Labs/pki-framework/tree/1.4.2"
},
"funding": [
{
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
+ "url": "https://github.com/Spomky",
"type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
+ "url": "https://www.patreon.com/FlorentMorselli",
+ "type": "patreon"
}
],
- "time": "2025-04-29T11:18:49+00:00"
+ "time": "2026-03-23T22:56:56+00:00"
},
{
- "name": "symfony/mailer",
- "version": "v7.3.5",
+ "name": "staabm/side-effects-detector",
+ "version": "1.0.5",
"source": {
"type": "git",
- "url": "https://github.com/symfony/mailer.git",
- "reference": "fd497c45ba9c10c37864e19466b090dcb60a50ba"
+ "url": "https://github.com/staabm/side-effects-detector.git",
+ "reference": "d8334211a140ce329c13726d4a715adbddd0a163"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mailer/zipball/fd497c45ba9c10c37864e19466b090dcb60a50ba",
- "reference": "fd497c45ba9c10c37864e19466b090dcb60a50ba",
+ "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163",
+ "reference": "d8334211a140ce329c13726d4a715adbddd0a163",
"shasum": ""
},
"require": {
- "egulias/email-validator": "^2.1.10|^3|^4",
- "php": ">=8.2",
- "psr/event-dispatcher": "^1",
- "psr/log": "^1|^2|^3",
- "symfony/event-dispatcher": "^6.4|^7.0",
- "symfony/mime": "^7.2",
- "symfony/service-contracts": "^2.5|^3"
- },
- "conflict": {
- "symfony/http-client-contracts": "<2.5",
- "symfony/http-kernel": "<6.4",
- "symfony/messenger": "<6.4",
- "symfony/mime": "<6.4",
- "symfony/twig-bridge": "<6.4"
+ "ext-tokenizer": "*",
+ "php": "^7.4 || ^8.0"
},
"require-dev": {
- "symfony/console": "^6.4|^7.0",
- "symfony/http-client": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
- "symfony/twig-bridge": "^6.4|^7.0"
+ "phpstan/extension-installer": "^1.4.3",
+ "phpstan/phpstan": "^1.12.6",
+ "phpunit/phpunit": "^9.6.21",
+ "symfony/var-dumper": "^5.4.43",
+ "tomasvotruba/type-coverage": "1.0.0",
+ "tomasvotruba/unused-public": "1.0.0"
},
"type": "library",
"autoload": {
- "psr-4": {
- "Symfony\\Component\\Mailer\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "lib/"
]
},
"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": "A static analysis tool to detect side effects in PHP code",
+ "keywords": [
+ "static analysis"
],
- "description": "Helps sending emails",
- "homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/mailer/tree/v7.3.5"
+ "issues": "https://github.com/staabm/side-effects-detector/issues",
+ "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5"
},
"funding": [
{
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
+ "url": "https://github.com/staabm",
"type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
}
],
- "time": "2025-10-24T14:27:20+00:00"
+ "time": "2024-10-20T05:08:20+00:00"
},
{
- "name": "symfony/mime",
- "version": "v7.3.4",
+ "name": "symfony/clock",
+ "version": "v7.4.8",
"source": {
"type": "git",
- "url": "https://github.com/symfony/mime.git",
- "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35"
+ "url": "https://github.com/symfony/clock.git",
+ "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mime/zipball/b1b828f69cbaf887fa835a091869e55df91d0e35",
- "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35",
+ "url": "https://api.github.com/repos/symfony/clock/zipball/674fa3b98e21531dd040e613479f5f6fa8f32111",
+ "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111",
"shasum": ""
},
"require": {
"php": ">=8.2",
- "symfony/polyfill-intl-idn": "^1.10",
- "symfony/polyfill-mbstring": "^1.0"
- },
- "conflict": {
- "egulias/email-validator": "~3.0.0",
- "phpdocumentor/reflection-docblock": "<3.2.2",
- "phpdocumentor/type-resolver": "<1.4.0",
- "symfony/mailer": "<6.4",
- "symfony/serializer": "<6.4.3|>7.0,<7.0.3"
+ "psr/clock": "^1.0",
+ "symfony/polyfill-php83": "^1.28"
},
- "require-dev": {
- "egulias/email-validator": "^2.1.10|^3.1|^4",
- "league/html-to-markdown": "^5.0",
- "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/property-access": "^6.4|^7.0",
- "symfony/property-info": "^6.4|^7.0",
- "symfony/serializer": "^6.4.3|^7.0.3"
+ "provide": {
+ "psr/clock-implementation": "1.0"
},
"type": "library",
"autoload": {
+ "files": [
+ "Resources/now.php"
+ ],
"psr-4": {
- "Symfony\\Component\\Mime\\": ""
+ "Symfony\\Component\\Clock\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -4420,22 +6419,23 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Allows manipulating MIME messages",
+ "description": "Decouples applications from the system clock",
"homepage": "https://symfony.com",
"keywords": [
- "mime",
- "mime-type"
+ "clock",
+ "psr20",
+ "time"
],
"support": {
- "source": "https://github.com/symfony/mime/tree/v7.3.4"
+ "source": "https://github.com/symfony/clock/tree/v7.4.8"
},
"funding": [
{
@@ -4455,45 +6455,33 @@
"type": "tidelift"
}
],
- "time": "2025-09-16T08:38:17+00:00"
+ "time": "2026-03-24T13:12:05+00:00"
},
{
- "name": "symfony/polyfill-ctype",
- "version": "v1.33.0",
+ "name": "symfony/css-selector",
+ "version": "v7.4.9",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
+ "url": "https://github.com/symfony/css-selector.git",
+ "reference": "b75663ed96cf4756e28e3105476f220f92886cc4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
- "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/b75663ed96cf4756e28e3105476f220f92886cc4",
+ "reference": "b75663ed96cf4756e28e3105476f220f92886cc4",
"shasum": ""
},
"require": {
- "php": ">=7.2"
- },
- "provide": {
- "ext-ctype": "*"
- },
- "suggest": {
- "ext-ctype": "For best performance"
+ "php": ">=8.2"
},
"type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
"autoload": {
- "files": [
- "bootstrap.php"
- ],
"psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- }
+ "Symfony\\Component\\CssSelector\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -4501,24 +6489,22 @@
],
"authors": [
{
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Jean-François Simon",
+ "email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill for ctype functions",
+ "description": "Converts CSS selectors to XPath expressions",
"homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
- ],
"support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0"
+ "source": "https://github.com/symfony/css-selector/tree/v7.4.9"
},
"funding": [
{
@@ -4538,45 +6524,40 @@
"type": "tidelift"
}
],
- "time": "2024-09-09T11:45:10+00:00"
+ "time": "2026-04-18T13:18:21+00:00"
},
{
- "name": "symfony/polyfill-iconv",
- "version": "v1.33.0",
+ "name": "symfony/dom-crawler",
+ "version": "v7.4.12",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-iconv.git",
- "reference": "5f3b930437ae03ae5dff61269024d8ea1b3774aa"
+ "url": "https://github.com/symfony/dom-crawler.git",
+ "reference": "b59b59122690976550fd142c23fab62c84738db6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/5f3b930437ae03ae5dff61269024d8ea1b3774aa",
- "reference": "5f3b930437ae03ae5dff61269024d8ea1b3774aa",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b59b59122690976550fd142c23fab62c84738db6",
+ "reference": "b59b59122690976550fd142c23fab62c84738db6",
"shasum": ""
},
"require": {
- "php": ">=7.2"
- },
- "provide": {
- "ext-iconv": "*"
+ "masterminds/html5": "^2.6",
+ "php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.0"
},
- "suggest": {
- "ext-iconv": "For best performance"
+ "require-dev": {
+ "symfony/css-selector": "^6.4|^7.0|^8.0"
},
"type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
"autoload": {
- "files": [
- "bootstrap.php"
- ],
"psr-4": {
- "Symfony\\Polyfill\\Iconv\\": ""
- }
+ "Symfony\\Component\\DomCrawler\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -4584,25 +6565,18 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill for the Iconv extension",
+ "description": "Eases DOM navigation for HTML and XML documents",
"homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "iconv",
- "polyfill",
- "portable",
- "shim"
- ],
"support": {
- "source": "https://github.com/symfony/polyfill-iconv/tree/v1.33.0"
+ "source": "https://github.com/symfony/dom-crawler/tree/v7.4.12"
},
"funding": [
{
@@ -4622,42 +6596,54 @@
"type": "tidelift"
}
],
- "time": "2024-09-17T14:58:18+00:00"
+ "time": "2026-05-20T07:20:23+00:00"
},
{
- "name": "symfony/polyfill-intl-grapheme",
- "version": "v1.33.0",
+ "name": "symfony/event-dispatcher",
+ "version": "v8.1.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
- "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70"
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "abd6c11dc468725d1627302ad10f6cd486e9e3d0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70",
- "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/abd6c11dc468725d1627302ad10f6cd486e9e3d0",
+ "reference": "abd6c11dc468725d1627302ad10f6cd486e9e3d0",
"shasum": ""
},
"require": {
- "php": ">=7.2"
+ "php": ">=8.4.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/event-dispatcher-contracts": "^2.5|^3"
},
- "suggest": {
- "ext-intl": "For best performance"
+ "conflict": {
+ "symfony/security-http": "<7.4",
+ "symfony/service-contracts": "<2.5"
},
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
+ "provide": {
+ "psr/event-dispatcher-implementation": "1.0",
+ "symfony/event-dispatcher-implementation": "2.0|3.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^7.4|^8.0",
+ "symfony/dependency-injection": "^7.4|^8.0",
+ "symfony/error-handler": "^7.4|^8.0",
+ "symfony/expression-language": "^7.4|^8.0",
+ "symfony/framework-bundle": "^7.4|^8.0",
+ "symfony/http-foundation": "^7.4|^8.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/stopwatch": "^7.4|^8.0"
},
+ "type": "library",
"autoload": {
- "files": [
- "bootstrap.php"
- ],
"psr-4": {
- "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
- }
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -4665,26 +6651,18 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill for intl's grapheme_* functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "grapheme",
- "intl",
- "polyfill",
- "portable",
- "shim"
- ],
+ "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": {
- "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0"
+ "source": "https://github.com/symfony/event-dispatcher/tree/v8.1.1"
},
"funding": [
{
@@ -4704,42 +6682,39 @@
"type": "tidelift"
}
],
- "time": "2025-06-27T09:58:17+00:00"
+ "time": "2026-06-09T12:28:30+00:00"
},
{
- "name": "symfony/polyfill-intl-idn",
- "version": "v1.33.0",
+ "name": "symfony/event-dispatcher-contracts",
+ "version": "v3.7.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-intl-idn.git",
- "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3"
+ "url": "https://github.com/symfony/event-dispatcher-contracts.git",
+ "reference": "c7de7a00ffb67842132da02ea92988a39ccd9f4e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3",
- "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c7de7a00ffb67842132da02ea92988a39ccd9f4e",
+ "reference": "c7de7a00ffb67842132da02ea92988a39ccd9f4e",
"shasum": ""
},
"require": {
- "php": ">=7.2",
- "symfony/polyfill-intl-normalizer": "^1.10"
- },
- "suggest": {
- "ext-intl": "For best performance"
+ "php": ">=8.1",
+ "psr/event-dispatcher": "^1"
},
"type": "library",
"extra": {
"thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
+ "url": "https://github.com/symfony/contracts",
+ "name": "symfony/contracts"
+ },
+ "branch-alias": {
+ "dev-main": "3.7-dev"
}
},
"autoload": {
- "files": [
- "bootstrap.php"
- ],
"psr-4": {
- "Symfony\\Polyfill\\Intl\\Idn\\": ""
+ "Symfony\\Contracts\\EventDispatcher\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -4748,30 +6723,26 @@
],
"authors": [
{
- "name": "Laurent Bassin",
- "email": "laurent@bassin.info"
- },
- {
- "name": "Trevor Rowbotham",
- "email": "trevor.rowbotham@pm.me"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+ "description": "Generic abstractions related to dispatching event",
"homepage": "https://symfony.com",
"keywords": [
- "compatibility",
- "idn",
- "intl",
- "polyfill",
- "portable",
- "shim"
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0"
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.1"
},
"funding": [
{
@@ -4791,44 +6762,37 @@
"type": "tidelift"
}
],
- "time": "2024-09-10T14:38:51+00:00"
+ "time": "2026-06-05T06:23:12+00:00"
},
{
- "name": "symfony/polyfill-intl-normalizer",
- "version": "v1.33.0",
+ "name": "symfony/filesystem",
+ "version": "v6.4.39",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "3833d7255cc303546435cb650316bff708a1c75c"
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "c507b077756b4e3e09adbbe7975fac81cd3722ca"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c",
- "reference": "3833d7255cc303546435cb650316bff708a1c75c",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/c507b077756b4e3e09adbbe7975fac81cd3722ca",
+ "reference": "c507b077756b4e3e09adbbe7975fac81cd3722ca",
"shasum": ""
},
"require": {
- "php": ">=7.2"
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.8"
},
- "suggest": {
- "ext-intl": "For best performance"
+ "require-dev": {
+ "symfony/process": "^5.4|^6.4|^7.0"
},
"type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
"autoload": {
- "files": [
- "bootstrap.php"
- ],
"psr-4": {
- "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ "Symfony\\Component\\Filesystem\\": ""
},
- "classmap": [
- "Resources/stubs"
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -4837,26 +6801,18 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "intl",
- "normalizer",
- "polyfill",
- "portable",
- "shim"
- ],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0"
+ "source": "https://github.com/symfony/filesystem/tree/v6.4.39"
},
"funding": [
{
@@ -4876,46 +6832,66 @@
"type": "tidelift"
}
],
- "time": "2024-09-09T11:45:10+00:00"
+ "time": "2026-05-07T13:11:42+00:00"
},
{
- "name": "symfony/polyfill-mbstring",
- "version": "v1.33.0",
+ "name": "symfony/http-client",
+ "version": "v7.4.14",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
+ "url": "https://github.com/symfony/http-client.git",
+ "reference": "f6bc6b5a54ff5afac4725cacec9bf2f52eb15920"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
- "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
+ "url": "https://api.github.com/repos/symfony/http-client/zipball/f6bc6b5a54ff5afac4725cacec9bf2f52eb15920",
+ "reference": "f6bc6b5a54ff5afac4725cacec9bf2f52eb15920",
"shasum": ""
},
"require": {
- "ext-iconv": "*",
- "php": ">=7.2"
+ "php": ">=8.2",
+ "psr/log": "^1|^2|^3",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/http-client-contracts": "~3.4.4|^3.5.2",
+ "symfony/polyfill-php83": "^1.29",
+ "symfony/service-contracts": "^2.5|^3"
+ },
+ "conflict": {
+ "amphp/amp": "<2.5",
+ "amphp/socket": "<1.1",
+ "php-http/discovery": "<1.15",
+ "symfony/http-foundation": "<6.4"
},
"provide": {
- "ext-mbstring": "*"
+ "php-http/async-client-implementation": "*",
+ "php-http/client-implementation": "*",
+ "psr/http-client-implementation": "1.0",
+ "symfony/http-client-implementation": "3.0"
},
- "suggest": {
- "ext-mbstring": "For best performance"
+ "require-dev": {
+ "amphp/http-client": "^4.2.1|^5.0",
+ "amphp/http-tunnel": "^1.0|^2.0",
+ "guzzlehttp/promises": "^1.4|^2.0",
+ "nyholm/psr7": "^1.0",
+ "php-http/httplug": "^1.0|^2.0",
+ "psr/http-client": "^1.0",
+ "symfony/amphp-http-client-meta": "^1.0|^2.0",
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/rate-limiter": "^6.4|^7.0|^8.0",
+ "symfony/stopwatch": "^6.4|^7.0|^8.0"
},
"type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
"autoload": {
- "files": [
- "bootstrap.php"
- ],
"psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
- }
+ "Symfony\\Component\\HttpClient\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -4931,17 +6907,13 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill for the Mbstring extension",
+ "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
"homepage": "https://symfony.com",
"keywords": [
- "compatibility",
- "mbstring",
- "polyfill",
- "portable",
- "shim"
+ "http"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0"
+ "source": "https://github.com/symfony/http-client/tree/v7.4.14"
},
"funding": [
{
@@ -4961,32 +6933,43 @@
"type": "tidelift"
}
],
- "time": "2024-12-23T08:48:59+00:00"
+ "time": "2026-06-16T11:50:14+00:00"
},
{
- "name": "symfony/polyfill-php72",
- "version": "v1.31.0",
+ "name": "symfony/http-client-contracts",
+ "version": "v3.7.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-php72.git",
- "reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce"
+ "url": "https://github.com/symfony/http-client-contracts.git",
+ "reference": "41fc42d276aeff21192465331ebbab7d83a743c0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce",
- "reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce",
+ "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/41fc42d276aeff21192465331ebbab7d83a743c0",
+ "reference": "41fc42d276aeff21192465331ebbab7d83a743c0",
"shasum": ""
},
"require": {
- "php": ">=7.2"
+ "php": ">=8.1"
},
- "type": "metapackage",
+ "type": "library",
"extra": {
"thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
+ "url": "https://github.com/symfony/contracts",
+ "name": "symfony/contracts"
+ },
+ "branch-alias": {
+ "dev-main": "3.7-dev"
}
},
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\HttpClient\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Test/"
+ ]
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
@@ -5001,16 +6984,18 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+ "description": "Generic abstractions related to HTTP clients",
"homepage": "https://symfony.com",
"keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php72/tree/v1.31.0"
+ "source": "https://github.com/symfony/http-client-contracts/tree/v3.7.1"
},
"funding": [
{
@@ -5021,46 +7006,60 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2024-09-09T11:45:10+00:00"
+ "time": "2026-06-05T06:23:12+00:00"
},
{
- "name": "symfony/polyfill-php81",
- "version": "v1.33.0",
+ "name": "symfony/mailer",
+ "version": "v7.4.14",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-php81.git",
- "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
+ "url": "https://github.com/symfony/mailer.git",
+ "reference": "f88ce03ae73e3edb5c176ce1f337709996e88495"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
- "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
+ "url": "https://api.github.com/repos/symfony/mailer/zipball/f88ce03ae73e3edb5c176ce1f337709996e88495",
+ "reference": "f88ce03ae73e3edb5c176ce1f337709996e88495",
"shasum": ""
},
"require": {
- "php": ">=7.2"
+ "egulias/email-validator": "^2.1.10|^3|^4",
+ "php": ">=8.2",
+ "psr/event-dispatcher": "^1",
+ "psr/log": "^1|^2|^3",
+ "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+ "symfony/mime": "^7.2|^8.0",
+ "symfony/service-contracts": "^2.5|^3"
},
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
+ "conflict": {
+ "symfony/http-client-contracts": "<2.5",
+ "symfony/http-kernel": "<6.4",
+ "symfony/messenger": "<6.4",
+ "symfony/mime": "<6.4",
+ "symfony/twig-bridge": "<6.4"
+ },
+ "require-dev": {
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/http-client": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
+ "symfony/twig-bridge": "^6.4|^7.0|^8.0"
},
+ "type": "library",
"autoload": {
- "files": [
- "bootstrap.php"
- ],
"psr-4": {
- "Symfony\\Polyfill\\Php81\\": ""
+ "Symfony\\Component\\Mailer\\": ""
},
- "classmap": [
- "Resources/stubs"
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -5069,24 +7068,18 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
+ "description": "Helps sending emails",
"homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
"support": {
- "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0"
+ "source": "https://github.com/symfony/mailer/tree/v7.4.14"
},
"funding": [
{
@@ -5106,41 +7099,52 @@
"type": "tidelift"
}
],
- "time": "2024-09-09T11:45:10+00:00"
+ "time": "2026-06-13T08:51:35+00:00"
},
{
- "name": "symfony/polyfill-php83",
- "version": "v1.33.0",
+ "name": "symfony/mime",
+ "version": "v7.4.13",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-php83.git",
- "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5"
+ "url": "https://github.com/symfony/mime.git",
+ "reference": "a845722765c4f6b2ce88beaf4f4479975b186770"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5",
- "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/a845722765c4f6b2ce88beaf4f4479975b186770",
+ "reference": "a845722765c4f6b2ce88beaf4f4479975b186770",
"shasum": ""
},
"require": {
- "php": ">=7.2"
+ "php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-intl-idn": "^1.10",
+ "symfony/polyfill-mbstring": "^1.0"
},
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
+ "conflict": {
+ "egulias/email-validator": "~3.0.0",
+ "phpdocumentor/reflection-docblock": "<5.2|>=7",
+ "phpdocumentor/type-resolver": "<1.5.1",
+ "symfony/mailer": "<6.4",
+ "symfony/serializer": "<6.4.3|>7.0,<7.0.3"
+ },
+ "require-dev": {
+ "egulias/email-validator": "^2.1.10|^3.1|^4",
+ "league/html-to-markdown": "^5.0",
+ "phpdocumentor/reflection-docblock": "^5.2|^6.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/property-access": "^6.4|^7.0|^8.0",
+ "symfony/property-info": "^6.4|^7.0|^8.0",
+ "symfony/serializer": "^6.4.3|^7.0.3|^8.0"
},
+ "type": "library",
"autoload": {
- "files": [
- "bootstrap.php"
- ],
"psr-4": {
- "Symfony\\Polyfill\\Php83\\": ""
+ "Symfony\\Component\\Mime\\": ""
},
- "classmap": [
- "Resources/stubs"
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -5149,24 +7153,22 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions",
+ "description": "Allows manipulating MIME messages",
"homepage": "https://symfony.com",
"keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
+ "mime",
+ "mime-type"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0"
+ "source": "https://github.com/symfony/mime/tree/v7.4.13"
},
"funding": [
{
@@ -5186,25 +7188,28 @@
"type": "tidelift"
}
],
- "time": "2025-07-08T02:45:35+00:00"
+ "time": "2026-05-23T16:22:37+00:00"
},
{
- "name": "symfony/polyfill-php84",
- "version": "v1.33.0",
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "v1.38.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-php84.git",
- "reference": "d8ced4d875142b6a7426000426b8abc631d6b191"
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "e9247d281d694a5120554d9afaf54e070e88a603"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191",
- "reference": "d8ced4d875142b6a7426000426b8abc631d6b191",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603",
+ "reference": "e9247d281d694a5120554d9afaf54e070e88a603",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
"type": "library",
"extra": {
"thanks": {
@@ -5217,11 +7222,8 @@
"bootstrap.php"
],
"psr-4": {
- "Symfony\\Polyfill\\Php84\\": ""
- },
- "classmap": [
- "Resources/stubs"
- ]
+ "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -5237,16 +7239,18 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions",
+ "description": "Symfony polyfill for intl's grapheme_* functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
+ "grapheme",
+ "intl",
"polyfill",
"portable",
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0"
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1"
},
"funding": [
{
@@ -5266,30 +7270,28 @@
"type": "tidelift"
}
],
- "time": "2025-06-24T13:30:11+00:00"
+ "time": "2026-05-26T05:58:03+00:00"
},
{
- "name": "symfony/polyfill-uuid",
- "version": "v1.33.0",
+ "name": "symfony/polyfill-intl-idn",
+ "version": "v1.38.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-uuid.git",
- "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2"
+ "url": "https://github.com/symfony/polyfill-intl-idn.git",
+ "reference": "dc21118016c039a66235cf93d96b435ffb282412"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2",
- "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/dc21118016c039a66235cf93d96b435ffb282412",
+ "reference": "dc21118016c039a66235cf93d96b435ffb282412",
"shasum": ""
},
"require": {
- "php": ">=7.2"
- },
- "provide": {
- "ext-uuid": "*"
+ "php": ">=7.2",
+ "symfony/polyfill-intl-normalizer": "^1.10"
},
"suggest": {
- "ext-uuid": "For best performance"
+ "ext-intl": "For best performance"
},
"type": "library",
"extra": {
@@ -5303,7 +7305,7 @@
"bootstrap.php"
],
"psr-4": {
- "Symfony\\Polyfill\\Uuid\\": ""
+ "Symfony\\Polyfill\\Intl\\Idn\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -5312,24 +7314,30 @@
],
"authors": [
{
- "name": "Grégoire Pineau",
- "email": "lyrixx@lyrixx.info"
+ "name": "Laurent Bassin",
+ "email": "laurent@bassin.info"
+ },
+ {
+ "name": "Trevor Rowbotham",
+ "email": "trevor.rowbotham@pm.me"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill for uuid functions",
+ "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
+ "idn",
+ "intl",
"polyfill",
"portable",
- "uuid"
+ "shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-uuid/tree/v1.33.0"
+ "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.38.1"
},
"funding": [
{
@@ -5349,32 +7357,44 @@
"type": "tidelift"
}
],
- "time": "2024-09-09T11:45:10+00:00"
+ "time": "2026-05-25T15:22:23+00:00"
},
{
- "name": "symfony/process",
- "version": "v7.3.4",
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.38.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/process.git",
- "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b"
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b",
- "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b",
+ "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b",
"shasum": ""
},
"require": {
- "php": ">=8.2"
+ "php": ">=7.2"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
},
"type": "library",
+ "extra": {
+ "thanks": {
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
+ }
+ },
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Component\\Process\\": ""
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
},
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -5383,18 +7403,26 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Executes commands in sub-processes",
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
"homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
"support": {
- "source": "https://github.com/symfony/process/tree/v7.3.4"
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0"
},
"funding": [
{
@@ -5414,36 +7442,41 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T10:12:26+00:00"
+ "time": "2026-05-25T13:48:31+00:00"
},
{
- "name": "symfony/property-access",
- "version": "v7.3.3",
+ "name": "symfony/polyfill-php80",
+ "version": "v1.37.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/property-access.git",
- "reference": "4a4389e5c8bd1d0320d80a23caa6a1ac71cb81a7"
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/property-access/zipball/4a4389e5c8bd1d0320d80a23caa6a1ac71cb81a7",
- "reference": "4a4389e5c8bd1d0320d80a23caa6a1ac71cb81a7",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411",
+ "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411",
"shasum": ""
},
"require": {
- "php": ">=8.2",
- "symfony/property-info": "^6.4|^7.0"
- },
- "require-dev": {
- "symfony/cache": "^6.4|^7.0"
+ "php": ">=7.2"
},
"type": "library",
+ "extra": {
+ "thanks": {
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
+ }
+ },
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Component\\PropertyAccess\\": ""
+ "Symfony\\Polyfill\\Php80\\": ""
},
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -5452,29 +7485,28 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Provides functions to read and write from/to an object or array using a simple string notation",
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
- "access",
- "array",
- "extraction",
- "index",
- "injection",
- "object",
- "property",
- "property-path",
- "reflection"
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
],
"support": {
- "source": "https://github.com/symfony/property-access/tree/v7.3.3"
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0"
},
"funding": [
{
@@ -5494,49 +7526,41 @@
"type": "tidelift"
}
],
- "time": "2025-08-04T15:15:28+00:00"
+ "time": "2026-04-10T16:19:22+00:00"
},
{
- "name": "symfony/property-info",
- "version": "v7.3.5",
+ "name": "symfony/polyfill-php83",
+ "version": "v1.38.2",
"source": {
"type": "git",
- "url": "https://github.com/symfony/property-info.git",
- "reference": "0b346ed259dc5da43535caf243005fe7d4b0f051"
+ "url": "https://github.com/symfony/polyfill-php83.git",
+ "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/property-info/zipball/0b346ed259dc5da43535caf243005fe7d4b0f051",
- "reference": "0b346ed259dc5da43535caf243005fe7d4b0f051",
+ "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/796a26abb75ce49f3a84433cd81bf1009d73d5f8",
+ "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8",
"shasum": ""
},
"require": {
- "php": ">=8.2",
- "symfony/deprecation-contracts": "^2.5|^3",
- "symfony/string": "^6.4|^7.0",
- "symfony/type-info": "^7.3.5"
- },
- "conflict": {
- "phpdocumentor/reflection-docblock": "<5.2",
- "phpdocumentor/type-resolver": "<1.5.1",
- "symfony/cache": "<6.4",
- "symfony/dependency-injection": "<6.4",
- "symfony/serializer": "<6.4"
- },
- "require-dev": {
- "phpdocumentor/reflection-docblock": "^5.2",
- "phpstan/phpdoc-parser": "^1.0|^2.0",
- "symfony/cache": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/serializer": "^6.4|^7.0"
+ "php": ">=7.2"
},
"type": "library",
+ "extra": {
+ "thanks": {
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
+ }
+ },
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Component\\PropertyInfo\\": ""
+ "Symfony\\Polyfill\\Php83\\": ""
},
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -5545,26 +7569,24 @@
],
"authors": [
{
- "name": "Kévin Dunglas",
- "email": "dunglas@gmail.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Extracts information about PHP class' properties using metadata of popular sources",
+ "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
- "doctrine",
- "phpdoc",
- "property",
- "symfony",
- "type",
- "validator"
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
],
"support": {
- "source": "https://github.com/symfony/property-info/tree/v7.3.5"
+ "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.2"
},
"funding": [
{
@@ -5584,69 +7606,41 @@
"type": "tidelift"
}
],
- "time": "2025-10-05T22:12:41+00:00"
+ "time": "2026-05-27T06:51:48+00:00"
},
{
- "name": "symfony/serializer",
- "version": "v6.4.27",
+ "name": "symfony/polyfill-php84",
+ "version": "v1.38.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/serializer.git",
- "reference": "28779bbdb398cac3421d0e51f7ca669e4a27c5ac"
+ "url": "https://github.com/symfony/polyfill-php84.git",
+ "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/serializer/zipball/28779bbdb398cac3421d0e51f7ca669e4a27c5ac",
- "reference": "28779bbdb398cac3421d0e51f7ca669e4a27c5ac",
+ "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa",
+ "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa",
"shasum": ""
},
"require": {
- "php": ">=8.1",
- "symfony/deprecation-contracts": "^2.5|^3",
- "symfony/polyfill-ctype": "~1.8"
- },
- "conflict": {
- "doctrine/annotations": "<1.12",
- "phpdocumentor/reflection-docblock": "<3.2.2",
- "phpdocumentor/type-resolver": "<1.4.0",
- "symfony/dependency-injection": "<5.4",
- "symfony/property-access": "<5.4",
- "symfony/property-info": "<5.4.24|>=6,<6.2.11",
- "symfony/uid": "<5.4",
- "symfony/validator": "<6.4",
- "symfony/yaml": "<5.4"
- },
- "require-dev": {
- "doctrine/annotations": "^1.12|^2",
- "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0",
- "seld/jsonlint": "^1.10",
- "symfony/cache": "^5.4|^6.0|^7.0",
- "symfony/config": "^5.4|^6.0|^7.0",
- "symfony/console": "^5.4|^6.0|^7.0",
- "symfony/dependency-injection": "^5.4|^6.0|^7.0",
- "symfony/error-handler": "^5.4|^6.0|^7.0",
- "symfony/filesystem": "^5.4|^6.0|^7.0",
- "symfony/form": "^5.4|^6.0|^7.0",
- "symfony/http-foundation": "^5.4|^6.0|^7.0",
- "symfony/http-kernel": "^5.4|^6.0|^7.0",
- "symfony/messenger": "^5.4|^6.0|^7.0",
- "symfony/mime": "^5.4|^6.0|^7.0",
- "symfony/property-access": "^5.4.26|^6.3|^7.0",
- "symfony/property-info": "^5.4.24|^6.2.11|^7.0",
- "symfony/translation-contracts": "^2.5|^3",
- "symfony/uid": "^5.4|^6.0|^7.0",
- "symfony/validator": "^6.4|^7.0",
- "symfony/var-dumper": "^5.4|^6.0|^7.0",
- "symfony/var-exporter": "^5.4|^6.0|^7.0",
- "symfony/yaml": "^5.4|^6.0|^7.0"
+ "php": ">=7.2"
},
"type": "library",
+ "extra": {
+ "thanks": {
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
+ }
+ },
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Component\\Serializer\\": ""
+ "Symfony\\Polyfill\\Php84\\": ""
},
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -5655,18 +7649,24 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
+ "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions",
"homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
"support": {
- "source": "https://github.com/symfony/serializer/tree/v6.4.27"
+ "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1"
},
"funding": [
{
@@ -5686,47 +7686,45 @@
"type": "tidelift"
}
],
- "time": "2025-10-08T04:24:22+00:00"
+ "time": "2026-05-26T12:51:13+00:00"
},
{
- "name": "symfony/service-contracts",
- "version": "v3.6.0",
+ "name": "symfony/polyfill-uuid",
+ "version": "v1.37.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/service-contracts.git",
- "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4"
+ "url": "https://github.com/symfony/polyfill-uuid.git",
+ "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
- "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
+ "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94",
+ "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94",
"shasum": ""
},
"require": {
- "php": ">=8.1",
- "psr/container": "^1.1|^2.0",
- "symfony/deprecation-contracts": "^2.5|^3"
+ "php": ">=7.2"
},
- "conflict": {
- "ext-psr": "<1.1|>=2"
+ "provide": {
+ "ext-uuid": "*"
+ },
+ "suggest": {
+ "ext-uuid": "For best performance"
},
"type": "library",
"extra": {
"thanks": {
- "url": "https://github.com/symfony/contracts",
- "name": "symfony/contracts"
- },
- "branch-alias": {
- "dev-main": "3.6-dev"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
- "psr-4": {
- "Symfony\\Contracts\\Service\\": ""
- },
- "exclude-from-classmap": [
- "/Test/"
- ]
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Uuid\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -5734,26 +7732,24 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Grégoire Pineau",
+ "email": "lyrixx@lyrixx.info"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Generic abstractions related to writing services",
+ "description": "Symfony polyfill for uuid functions",
"homepage": "https://symfony.com",
"keywords": [
- "abstractions",
- "contracts",
- "decoupling",
- "interfaces",
- "interoperability",
- "standards"
+ "compatibility",
+ "polyfill",
+ "portable",
+ "uuid"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.6.0"
+ "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0"
},
"funding": [
{
@@ -5764,51 +7760,38 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2025-04-25T09:37:31+00:00"
+ "time": "2026-04-10T16:19:22+00:00"
},
{
- "name": "symfony/string",
- "version": "v7.3.4",
+ "name": "symfony/process",
+ "version": "v7.4.13",
"source": {
"type": "git",
- "url": "https://github.com/symfony/string.git",
- "reference": "f96476035142921000338bad71e5247fbc138872"
+ "url": "https://github.com/symfony/process.git",
+ "reference": "f5804be144caceb570f6747519999636b664f24c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872",
- "reference": "f96476035142921000338bad71e5247fbc138872",
+ "url": "https://api.github.com/repos/symfony/process/zipball/f5804be144caceb570f6747519999636b664f24c",
+ "reference": "f5804be144caceb570f6747519999636b664f24c",
"shasum": ""
},
"require": {
- "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"
- },
- "conflict": {
- "symfony/translation-contracts": "<2.5"
- },
- "require-dev": {
- "symfony/emoji": "^7.1",
- "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"
+ "php": ">=8.2"
},
"type": "library",
"autoload": {
- "files": [
- "Resources/functions.php"
- ],
"psr-4": {
- "Symfony\\Component\\String\\": ""
+ "Symfony\\Component\\Process\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -5820,26 +7803,18 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+ "description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
- "keywords": [
- "grapheme",
- "i18n",
- "string",
- "unicode",
- "utf-8",
- "utf8"
- ],
"support": {
- "source": "https://github.com/symfony/string/tree/v7.3.4"
+ "source": "https://github.com/symfony/process/tree/v7.4.13"
},
"funding": [
{
@@ -5859,37 +7834,34 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T14:36:48+00:00"
+ "time": "2026-05-23T16:05:06+00:00"
},
{
- "name": "symfony/type-info",
- "version": "v7.3.5",
+ "name": "symfony/property-access",
+ "version": "v7.4.8",
"source": {
"type": "git",
- "url": "https://github.com/symfony/type-info.git",
- "reference": "8b36f41421160db56914f897b57eaa6a830758b3"
+ "url": "https://github.com/symfony/property-access.git",
+ "reference": "b7dad9dae8b8a47ef7ecc76c8569e7d8c7d90cfc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/type-info/zipball/8b36f41421160db56914f897b57eaa6a830758b3",
- "reference": "8b36f41421160db56914f897b57eaa6a830758b3",
+ "url": "https://api.github.com/repos/symfony/property-access/zipball/b7dad9dae8b8a47ef7ecc76c8569e7d8c7d90cfc",
+ "reference": "b7dad9dae8b8a47ef7ecc76c8569e7d8c7d90cfc",
"shasum": ""
},
"require": {
"php": ">=8.2",
- "psr/container": "^1.1|^2.0",
- "symfony/deprecation-contracts": "^2.5|^3"
- },
- "conflict": {
- "phpstan/phpdoc-parser": "<1.30"
+ "symfony/property-info": "^6.4.32|~7.3.10|^7.4.4|^8.0.4"
},
"require-dev": {
- "phpstan/phpdoc-parser": "^1.30|^2.0"
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/var-exporter": "^6.4.1|^7.0.1|^8.0"
},
"type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Component\\TypeInfo\\": ""
+ "Symfony\\Component\\PropertyAccess\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -5901,28 +7873,29 @@
],
"authors": [
{
- "name": "Mathias Arlaud",
- "email": "mathias.arlaud@gmail.com"
- },
- {
- "name": "Baptiste LEDUC",
- "email": "baptiste.leduc@gmail.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Extracts PHP types information.",
+ "description": "Provides functions to read and write from/to an object or array using a simple string notation",
"homepage": "https://symfony.com",
"keywords": [
- "PHPStan",
- "phpdoc",
- "symfony",
- "type"
+ "access",
+ "array",
+ "extraction",
+ "index",
+ "injection",
+ "object",
+ "property",
+ "property-path",
+ "reflection"
],
"support": {
- "source": "https://github.com/symfony/type-info/tree/v7.3.5"
+ "source": "https://github.com/symfony/property-access/tree/v7.4.8"
},
"funding": [
{
@@ -5942,33 +7915,46 @@
"type": "tidelift"
}
],
- "time": "2025-10-16T12:30:12+00:00"
+ "time": "2026-03-24T13:12:05+00:00"
},
{
- "name": "symfony/uid",
- "version": "v7.3.1",
+ "name": "symfony/property-info",
+ "version": "v7.4.8",
"source": {
"type": "git",
- "url": "https://github.com/symfony/uid.git",
- "reference": "a69f69f3159b852651a6bf45a9fdd149520525bb"
+ "url": "https://github.com/symfony/property-info.git",
+ "reference": "ac5e82528b986c4f7cfccbf7764b5d2e824d6175"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/uid/zipball/a69f69f3159b852651a6bf45a9fdd149520525bb",
- "reference": "a69f69f3159b852651a6bf45a9fdd149520525bb",
+ "url": "https://api.github.com/repos/symfony/property-info/zipball/ac5e82528b986c4f7cfccbf7764b5d2e824d6175",
+ "reference": "ac5e82528b986c4f7cfccbf7764b5d2e824d6175",
"shasum": ""
},
"require": {
"php": ">=8.2",
- "symfony/polyfill-uuid": "^1.15"
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/string": "^6.4|^7.0|^8.0",
+ "symfony/type-info": "^7.4.7|^8.0.7"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "<5.2|>=7",
+ "phpdocumentor/type-resolver": "<1.5.1",
+ "symfony/cache": "<6.4",
+ "symfony/dependency-injection": "<6.4",
+ "symfony/serializer": "<6.4"
},
"require-dev": {
- "symfony/console": "^6.4|^7.0"
+ "phpdocumentor/reflection-docblock": "^5.2|^6.0",
+ "phpstan/phpdoc-parser": "^1.0|^2.0",
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/serializer": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Component\\Uid\\": ""
+ "Symfony\\Component\\PropertyInfo\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -5980,27 +7966,26 @@
],
"authors": [
{
- "name": "Grégoire Pineau",
- "email": "lyrixx@lyrixx.info"
- },
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Kévin Dunglas",
+ "email": "dunglas@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Provides an object-oriented API to generate and represent UIDs",
+ "description": "Extracts information about PHP class' properties using metadata of popular sources",
"homepage": "https://symfony.com",
"keywords": [
- "UID",
- "ulid",
- "uuid"
+ "doctrine",
+ "phpdoc",
+ "property",
+ "symfony",
+ "type",
+ "validator"
],
"support": {
- "source": "https://github.com/symfony/uid/tree/v7.3.1"
+ "source": "https://github.com/symfony/property-info/tree/v7.4.8"
},
"funding": [
{
@@ -6011,52 +7996,77 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2025-06-27T19:55:54+00:00"
+ "time": "2026-03-24T13:12:05+00:00"
},
{
- "name": "symfony/var-dumper",
- "version": "v7.3.5",
+ "name": "symfony/serializer",
+ "version": "v7.4.14",
"source": {
"type": "git",
- "url": "https://github.com/symfony/var-dumper.git",
- "reference": "476c4ae17f43a9a36650c69879dcf5b1e6ae724d"
+ "url": "https://github.com/symfony/serializer.git",
+ "reference": "55acb01b9c8a5211dfbaf68c314d90d0ed2cc3d1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/476c4ae17f43a9a36650c69879dcf5b1e6ae724d",
- "reference": "476c4ae17f43a9a36650c69879dcf5b1e6ae724d",
+ "url": "https://api.github.com/repos/symfony/serializer/zipball/55acb01b9c8a5211dfbaf68c314d90d0ed2cc3d1",
+ "reference": "55acb01b9c8a5211dfbaf68c314d90d0ed2cc3d1",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/polyfill-mbstring": "~1.0"
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-php84": "^1.30"
},
"conflict": {
- "symfony/console": "<6.4"
+ "phpdocumentor/reflection-docblock": "<5.2|>=7",
+ "phpdocumentor/type-resolver": "<1.5.1",
+ "symfony/dependency-injection": "<6.4",
+ "symfony/property-access": "<6.4.31|>=7.0,<7.4.2|>=8.0,<8.0.2",
+ "symfony/property-info": "<6.4",
+ "symfony/type-info": "<7.2.5",
+ "symfony/uid": "<6.4",
+ "symfony/validator": "<6.4",
+ "symfony/yaml": "<6.4"
},
"require-dev": {
- "symfony/console": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/uid": "^6.4|^7.0",
- "twig/twig": "^3.12"
+ "phpdocumentor/reflection-docblock": "^5.2|^6.0",
+ "phpstan/phpdoc-parser": "^1.0|^2.0",
+ "seld/jsonlint": "^1.10",
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^7.2|^8.0",
+ "symfony/error-handler": "^6.4|^7.0|^8.0",
+ "symfony/filesystem": "^6.4|^7.0|^8.0",
+ "symfony/form": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
+ "symfony/mime": "^6.4|^7.0|^8.0",
+ "symfony/property-access": "^6.4.31|^7.4.2|^8.0.2",
+ "symfony/property-info": "^6.4|^7.0|^8.0",
+ "symfony/translation-contracts": "^2.5|^3",
+ "symfony/type-info": "^7.2.5|^8.0",
+ "symfony/uid": "^6.4|^7.0|^8.0",
+ "symfony/validator": "^6.4|^7.0|^8.0",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0",
+ "symfony/var-exporter": "^6.4|^7.0|^8.0",
+ "symfony/yaml": "^6.4|^7.0|^8.0"
},
- "bin": [
- "Resources/bin/var-dump-server"
- ],
"type": "library",
"autoload": {
- "files": [
- "Resources/functions/dump.php"
- ],
"psr-4": {
- "Symfony\\Component\\VarDumper\\": ""
+ "Symfony\\Component\\Serializer\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -6068,22 +8078,18 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Provides mechanisms for walking through any arbitrary PHP variable",
+ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
"homepage": "https://symfony.com",
- "keywords": [
- "debug",
- "dump"
- ],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v7.3.5"
+ "source": "https://github.com/symfony/serializer/tree/v7.4.14"
},
"funding": [
{
@@ -6103,43 +8109,46 @@
"type": "tidelift"
}
],
- "time": "2025-09-27T09:00:46+00:00"
+ "time": "2026-06-27T08:31:18+00:00"
},
{
- "name": "symfony/yaml",
- "version": "v7.3.5",
+ "name": "symfony/service-contracts",
+ "version": "v3.7.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/yaml.git",
- "reference": "90208e2fc6f68f613eae7ca25a2458a931b1bacc"
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/90208e2fc6f68f613eae7ca25a2458a931b1bacc",
- "reference": "90208e2fc6f68f613eae7ca25a2458a931b1bacc",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0",
+ "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0",
"shasum": ""
},
"require": {
- "php": ">=8.2",
- "symfony/deprecation-contracts": "^2.5|^3.0",
- "symfony/polyfill-ctype": "^1.8"
+ "php": ">=8.1",
+ "psr/container": "^1.1|^2.0",
+ "symfony/deprecation-contracts": "^2.5|^3"
},
"conflict": {
- "symfony/console": "<6.4"
- },
- "require-dev": {
- "symfony/console": "^6.4|^7.0"
+ "ext-psr": "<1.1|>=2"
},
- "bin": [
- "Resources/bin/yaml-lint"
- ],
"type": "library",
+ "extra": {
+ "thanks": {
+ "url": "https://github.com/symfony/contracts",
+ "name": "symfony/contracts"
+ },
+ "branch-alias": {
+ "dev-main": "3.7-dev"
+ }
+ },
"autoload": {
"psr-4": {
- "Symfony\\Component\\Yaml\\": ""
+ "Symfony\\Contracts\\Service\\": ""
},
"exclude-from-classmap": [
- "/Tests/"
+ "/Test/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -6148,18 +8157,26 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Loads and dumps YAML files",
+ "description": "Generic abstractions related to writing services",
"homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
"support": {
- "source": "https://github.com/symfony/yaml/tree/v7.3.5"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.7.1"
},
"funding": [
{
@@ -6179,166 +8196,231 @@
"type": "tidelift"
}
],
- "time": "2025-09-27T09:00:46+00:00"
+ "time": "2026-06-16T09:55:08+00:00"
},
{
- "name": "theiconic/name-parser",
- "version": "v1.2.11",
+ "name": "symfony/string",
+ "version": "v8.1.0",
"source": {
"type": "git",
- "url": "https://github.com/theiconic/name-parser.git",
- "reference": "9a54a713bf5b2e7fd990828147d42de16bf8a253"
+ "url": "https://github.com/symfony/string.git",
+ "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theiconic/name-parser/zipball/9a54a713bf5b2e7fd990828147d42de16bf8a253",
- "reference": "9a54a713bf5b2e7fd990828147d42de16bf8a253",
+ "url": "https://api.github.com/repos/symfony/string/zipball/afd5944f4005862d961efb85c8bbd5c523c4e3c9",
+ "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=8.4.1",
+ "symfony/polyfill-ctype": "^1.8",
+ "symfony/polyfill-intl-grapheme": "^1.33",
+ "symfony/polyfill-intl-normalizer": "^1.0",
+ "symfony/polyfill-mbstring": "^1.0"
+ },
+ "conflict": {
+ "symfony/translation-contracts": "<2.5"
},
"require-dev": {
- "php-coveralls/php-coveralls": "^2.1",
- "php-mock/php-mock-phpunit": "^2.1",
- "phpunit/phpunit": "^7.0"
+ "symfony/emoji": "^7.4|^8.0",
+ "symfony/http-client": "^7.4|^8.0",
+ "symfony/intl": "^7.4|^8.0",
+ "symfony/translation-contracts": "^2.5|^3.0",
+ "symfony/var-exporter": "^7.4|^8.0"
},
"type": "library",
"autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
"psr-4": {
- "TheIconic\\NameParser\\": [
- "src/",
- "tests/"
- ]
- }
+ "Symfony\\Component\\String\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "authors": [
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "grapheme",
+ "i18n",
+ "string",
+ "unicode",
+ "utf-8",
+ "utf8"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v8.1.0"
+ },
+ "funding": [
{
- "name": "The Iconic",
- "email": "engineering@theiconic.com.au"
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
}
],
- "description": "PHP library for parsing a string containing a full name into its parts",
- "support": {
- "issues": "https://github.com/theiconic/name-parser/issues",
- "source": "https://github.com/theiconic/name-parser/tree/v1.2.11"
- },
- "time": "2019-11-14T14:08:48+00:00"
+ "time": "2026-05-29T05:06:50+00:00"
},
{
- "name": "twig/twig",
- "version": "v3.15.0",
+ "name": "symfony/translation",
+ "version": "v6.4.42",
"source": {
"type": "git",
- "url": "https://github.com/twigphp/Twig.git",
- "reference": "2d5b3964cc21d0188633d7ddce732dc8e874db02"
+ "url": "https://github.com/symfony/translation.git",
+ "reference": "fef99cef37890b350976f5f492854faefadd4e15"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/2d5b3964cc21d0188633d7ddce732dc8e874db02",
- "reference": "2d5b3964cc21d0188633d7ddce732dc8e874db02",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/fef99cef37890b350976f5f492854faefadd4e15",
+ "reference": "fef99cef37890b350976f5f492854faefadd4e15",
"shasum": ""
},
"require": {
- "php": ">=8.0.2",
+ "php": ">=8.1",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/polyfill-ctype": "^1.8",
- "symfony/polyfill-mbstring": "^1.3",
- "symfony/polyfill-php81": "^1.29"
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/translation-contracts": "^2.5|^3.0"
+ },
+ "conflict": {
+ "symfony/config": "<5.4",
+ "symfony/console": "<5.4",
+ "symfony/dependency-injection": "<5.4",
+ "symfony/http-client-contracts": "<2.5",
+ "symfony/http-kernel": "<5.4",
+ "symfony/service-contracts": "<2.5",
+ "symfony/twig-bundle": "<5.4",
+ "symfony/yaml": "<5.4"
+ },
+ "provide": {
+ "symfony/translation-implementation": "2.3|3.0"
},
"require-dev": {
- "psr/container": "^1.0|^2.0",
- "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
+ "nikic/php-parser": "^4.18|^5.0",
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^5.4|^6.0|^7.0",
+ "symfony/console": "^5.4|^6.0|^7.0",
+ "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+ "symfony/finder": "^5.4|^6.0|^7.0",
+ "symfony/http-client-contracts": "^2.5|^3.0",
+ "symfony/http-kernel": "^5.4|^6.0|^7.0",
+ "symfony/intl": "^5.4|^6.0|^7.0",
+ "symfony/polyfill-intl-icu": "^1.21",
+ "symfony/routing": "^5.4|^6.0|^7.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/yaml": "^5.4|^6.0|^7.0"
},
"type": "library",
"autoload": {
"files": [
- "src/Resources/core.php",
- "src/Resources/debug.php",
- "src/Resources/escaper.php",
- "src/Resources/string_loader.php"
+ "Resources/functions.php"
],
"psr-4": {
- "Twig\\": "src/"
- }
+ "Symfony\\Component\\Translation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com",
- "homepage": "http://fabien.potencier.org",
- "role": "Lead Developer"
- },
- {
- "name": "Twig Team",
- "role": "Contributors"
+ "email": "fabien@symfony.com"
},
{
- "name": "Armin Ronacher",
- "email": "armin.ronacher@active-4.com",
- "role": "Project Founder"
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Twig, the flexible, fast, and secure template language for PHP",
- "homepage": "https://twig.symfony.com",
- "keywords": [
- "templating"
- ],
+ "description": "Provides tools to internationalize your application",
+ "homepage": "https://symfony.com",
"support": {
- "issues": "https://github.com/twigphp/Twig/issues",
- "source": "https://github.com/twigphp/Twig/tree/v3.15.0"
+ "source": "https://github.com/symfony/translation/tree/v6.4.42"
},
"funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2024-11-17T15:59:19+00:00"
+ "time": "2026-06-05T16:46:18+00:00"
},
{
- "name": "voku/anti-xss",
- "version": "4.1.42",
+ "name": "symfony/translation-contracts",
+ "version": "v3.7.1",
"source": {
"type": "git",
- "url": "https://github.com/voku/anti-xss.git",
- "reference": "bca1f8607e55a3c5077483615cd93bd8f11bd675"
+ "url": "https://github.com/symfony/translation-contracts.git",
+ "reference": "ccb206b98faccc511ebae8e5fad50f2dc0b30621"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/voku/anti-xss/zipball/bca1f8607e55a3c5077483615cd93bd8f11bd675",
- "reference": "bca1f8607e55a3c5077483615cd93bd8f11bd675",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/ccb206b98faccc511ebae8e5fad50f2dc0b30621",
+ "reference": "ccb206b98faccc511ebae8e5fad50f2dc0b30621",
"shasum": ""
},
"require": {
- "php": ">=7.0.0",
- "voku/portable-utf8": "~6.0.2"
- },
- "require-dev": {
- "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0"
+ "php": ">=8.1"
},
"type": "library",
"extra": {
+ "thanks": {
+ "url": "https://github.com/symfony/contracts",
+ "name": "symfony/contracts"
+ },
"branch-alias": {
- "dev-master": "4.1.x-dev"
+ "dev-main": "3.7-dev"
}
},
"autoload": {
"psr-4": {
- "voku\\helper\\": "src/voku/helper/"
- }
+ "Symfony\\Contracts\\Translation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Test/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -6346,82 +8428,79 @@
],
"authors": [
{
- "name": "EllisLab Dev Team",
- "homepage": "http://ellislab.com/"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
- "name": "Lars Moelleken",
- "email": "lars@moelleken.org",
- "homepage": "https://www.moelleken.org/"
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "anti xss-library",
- "homepage": "https://github.com/voku/anti-xss",
+ "description": "Generic abstractions related to translation",
+ "homepage": "https://symfony.com",
"keywords": [
- "anti-xss",
- "clean",
- "security",
- "xss"
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
],
"support": {
- "issues": "https://github.com/voku/anti-xss/issues",
- "source": "https://github.com/voku/anti-xss/tree/4.1.42"
+ "source": "https://github.com/symfony/translation-contracts/tree/v3.7.1"
},
"funding": [
{
- "url": "https://www.paypal.me/moelleken",
+ "url": "https://symfony.com/sponsor",
"type": "custom"
},
{
- "url": "https://github.com/voku",
+ "url": "https://github.com/fabpot",
"type": "github"
},
{
- "url": "https://opencollective.com/anti-xss",
- "type": "open_collective"
- },
- {
- "url": "https://www.patreon.com/voku",
- "type": "patreon"
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/voku/anti-xss",
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2023-07-03T14:40:46+00:00"
+ "time": "2026-06-05T06:23:12+00:00"
},
{
- "name": "voku/arrayy",
- "version": "7.9.6",
+ "name": "symfony/type-info",
+ "version": "v8.1.0",
"source": {
"type": "git",
- "url": "https://github.com/voku/Arrayy.git",
- "reference": "0e20b8c6eef7fc46694a2906e0eae2f9fc11cade"
+ "url": "https://github.com/symfony/type-info.git",
+ "reference": "9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/voku/Arrayy/zipball/0e20b8c6eef7fc46694a2906e0eae2f9fc11cade",
- "reference": "0e20b8c6eef7fc46694a2906e0eae2f9fc11cade",
+ "url": "https://api.github.com/repos/symfony/type-info/zipball/9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7",
+ "reference": "9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7",
"shasum": ""
},
"require": {
- "ext-json": "*",
- "php": ">=7.0.0",
- "phpdocumentor/reflection-docblock": "~4.3 || ~5.0",
- "symfony/polyfill-mbstring": "~1.0"
+ "php": ">=8.4.1",
+ "psr/container": "^1.1|^2.0"
+ },
+ "conflict": {
+ "phpstan/phpdoc-parser": "<1.30"
},
"require-dev": {
- "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0"
+ "phpstan/phpdoc-parser": "^1.30|^2.0"
},
"type": "library",
"autoload": {
- "files": [
- "src/Create.php"
- ],
"psr-4": {
- "Arrayy\\": "src/"
- }
+ "Symfony\\Component\\TypeInfo\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -6429,81 +8508,78 @@
],
"authors": [
{
- "name": "Lars Moelleken",
- "email": "lars@moelleken.org",
- "homepage": "https://www.moelleken.org/",
- "role": "Maintainer"
+ "name": "Mathias Arlaud",
+ "email": "mathias.arlaud@gmail.com"
+ },
+ {
+ "name": "Baptiste LEDUC",
+ "email": "baptiste.leduc@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Array manipulation library for PHP, called Arrayy!",
+ "description": "Extracts PHP types information.",
+ "homepage": "https://symfony.com",
"keywords": [
- "Arrayy",
- "array",
- "helpers",
- "manipulation",
- "methods",
- "utility",
- "utils"
+ "PHPStan",
+ "phpdoc",
+ "symfony",
+ "type"
],
"support": {
- "docs": "https://voku.github.io/Arrayy/",
- "issues": "https://github.com/voku/Arrayy/issues",
- "source": "https://github.com/voku/Arrayy"
+ "source": "https://github.com/symfony/type-info/tree/v8.1.0"
},
"funding": [
{
- "url": "https://www.paypal.me/moelleken",
+ "url": "https://symfony.com/sponsor",
"type": "custom"
},
{
- "url": "https://github.com/voku",
+ "url": "https://github.com/fabpot",
"type": "github"
},
{
- "url": "https://opencollective.com/arrayy",
- "type": "open_collective"
- },
- {
- "url": "https://www.patreon.com/voku",
- "type": "patreon"
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/voku/arrayy",
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2022-12-27T12:58:32+00:00"
+ "time": "2026-05-29T05:06:50+00:00"
},
{
- "name": "voku/email-check",
- "version": "3.1.0",
+ "name": "symfony/uid",
+ "version": "v7.4.9",
"source": {
"type": "git",
- "url": "https://github.com/voku/email-check.git",
- "reference": "6ea842920bbef6758b8c1e619fd1710e7a1a2cac"
+ "url": "https://github.com/symfony/uid.git",
+ "reference": "2676b524340abcfe4d6151ec698463cebafee439"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/voku/email-check/zipball/6ea842920bbef6758b8c1e619fd1710e7a1a2cac",
- "reference": "6ea842920bbef6758b8c1e619fd1710e7a1a2cac",
+ "url": "https://api.github.com/repos/symfony/uid/zipball/2676b524340abcfe4d6151ec698463cebafee439",
+ "reference": "2676b524340abcfe4d6151ec698463cebafee439",
"shasum": ""
},
"require": {
- "php": ">=7.0.0",
- "symfony/polyfill-intl-idn": "~1.10"
+ "php": ">=8.2",
+ "symfony/polyfill-uuid": "^1.15"
},
"require-dev": {
- "fzaninotto/faker": "~1.7",
- "phpunit/phpunit": "~6.0 || ~7.0"
- },
- "suggest": {
- "ext-intl": "Use Intl for best performance"
+ "symfony/console": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
"psr-4": {
- "voku\\helper\\": "src/voku/helper/"
- }
+ "Symfony\\Component\\Uid\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -6511,73 +8587,91 @@
],
"authors": [
{
- "name": "Lars Moelleken",
- "homepage": "http://www.moelleken.org/"
+ "name": "Grégoire Pineau",
+ "email": "lyrixx@lyrixx.info"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "email-check (syntax, dns, trash, ...) library",
- "homepage": "https://github.com/voku/email-check",
+ "description": "Provides an object-oriented API to generate and represent UIDs",
+ "homepage": "https://symfony.com",
"keywords": [
- "check-email",
- "email",
- "mail",
- "mail-check",
- "validate-email",
- "validate-email-address",
- "validate-mail"
+ "UID",
+ "ulid",
+ "uuid"
],
"support": {
- "issues": "https://github.com/voku/email-check/issues",
- "source": "https://github.com/voku/email-check/tree/3.1.0"
+ "source": "https://github.com/symfony/uid/tree/v7.4.9"
},
"funding": [
{
- "url": "https://www.paypal.me/moelleken",
+ "url": "https://symfony.com/sponsor",
"type": "custom"
},
{
- "url": "https://github.com/voku",
+ "url": "https://github.com/fabpot",
"type": "github"
},
{
- "url": "https://www.patreon.com/voku",
- "type": "patreon"
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/voku/email-check",
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2021-01-27T14:14:33+00:00"
+ "time": "2026-04-30T15:19:22+00:00"
},
{
- "name": "voku/portable-ascii",
- "version": "2.0.3",
+ "name": "symfony/var-dumper",
+ "version": "v7.4.14",
"source": {
"type": "git",
- "url": "https://github.com/voku/portable-ascii.git",
- "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d"
+ "url": "https://github.com/symfony/var-dumper.git",
+ "reference": "9a3a56a4a1e65a5cb4f8d13801fe8ab0a170e358"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d",
- "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9a3a56a4a1e65a5cb4f8d13801fe8ab0a170e358",
+ "reference": "9a3a56a4a1e65a5cb4f8d13801fe8ab0a170e358",
"shasum": ""
},
"require": {
- "php": ">=7.0.0"
+ "php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-mbstring": "~1.0"
},
- "require-dev": {
- "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0"
+ "conflict": {
+ "symfony/console": "<6.4"
},
- "suggest": {
- "ext-intl": "Use Intl for transliterator_transliterate() support"
+ "require-dev": {
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/uid": "^6.4|^7.0|^8.0",
+ "twig/twig": "^3.12"
},
+ "bin": [
+ "Resources/bin/var-dump-server"
+ ],
"type": "library",
"autoload": {
+ "files": [
+ "Resources/functions/dump.php"
+ ],
"psr-4": {
- "voku\\": "src/voku/"
- }
+ "Symfony\\Component\\VarDumper\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -6585,172 +8679,148 @@
],
"authors": [
{
- "name": "Lars Moelleken",
- "homepage": "https://www.moelleken.org/"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Portable ASCII library - performance optimized (ascii) string functions for php.",
- "homepage": "https://github.com/voku/portable-ascii",
+ "description": "Provides mechanisms for walking through any arbitrary PHP variable",
+ "homepage": "https://symfony.com",
"keywords": [
- "ascii",
- "clean",
- "php"
+ "debug",
+ "dump"
],
"support": {
- "issues": "https://github.com/voku/portable-ascii/issues",
- "source": "https://github.com/voku/portable-ascii/tree/2.0.3"
+ "source": "https://github.com/symfony/var-dumper/tree/v7.4.14"
},
"funding": [
{
- "url": "https://www.paypal.me/moelleken",
+ "url": "https://symfony.com/sponsor",
"type": "custom"
},
{
- "url": "https://github.com/voku",
+ "url": "https://github.com/fabpot",
"type": "github"
},
{
- "url": "https://opencollective.com/portable-ascii",
- "type": "open_collective"
- },
- {
- "url": "https://www.patreon.com/voku",
- "type": "patreon"
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii",
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2024-11-21T01:49:47+00:00"
+ "time": "2026-06-08T20:24:16+00:00"
},
{
- "name": "voku/portable-utf8",
- "version": "6.0.13",
+ "name": "symfony/yaml",
+ "version": "v7.4.14",
"source": {
"type": "git",
- "url": "https://github.com/voku/portable-utf8.git",
- "reference": "b8ce36bf26593e5c2e81b1850ef0ffb299d2043f"
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "f8f328665ace2370d1e10645b807ba1646dc7dcc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/voku/portable-utf8/zipball/b8ce36bf26593e5c2e81b1850ef0ffb299d2043f",
- "reference": "b8ce36bf26593e5c2e81b1850ef0ffb299d2043f",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/f8f328665ace2370d1e10645b807ba1646dc7dcc",
+ "reference": "f8f328665ace2370d1e10645b807ba1646dc7dcc",
"shasum": ""
},
"require": {
- "php": ">=7.0.0",
- "symfony/polyfill-iconv": "~1.0",
- "symfony/polyfill-intl-grapheme": "~1.0",
- "symfony/polyfill-intl-normalizer": "~1.0",
- "symfony/polyfill-mbstring": "~1.0",
- "symfony/polyfill-php72": "~1.0",
- "voku/portable-ascii": "~2.0.0"
+ "php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-ctype": "^1.8"
},
- "require-dev": {
- "phpstan/phpstan": "1.9.*@dev",
- "phpstan/phpstan-strict-rules": "1.4.*@dev",
- "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0",
- "thecodingmachine/phpstan-strict-rules": "1.0.*@dev",
- "voku/phpstan-rules": "3.1.*@dev"
+ "conflict": {
+ "symfony/console": "<6.4"
},
- "suggest": {
- "ext-ctype": "Use Ctype for e.g. hexadecimal digit detection",
- "ext-fileinfo": "Use Fileinfo for better binary file detection",
- "ext-iconv": "Use iconv for best performance",
- "ext-intl": "Use Intl for best performance",
- "ext-json": "Use JSON for string detection",
- "ext-mbstring": "Use Mbstring for best performance"
+ "require-dev": {
+ "symfony/console": "^6.4|^7.0|^8.0"
},
+ "bin": [
+ "Resources/bin/yaml-lint"
+ ],
"type": "library",
"autoload": {
- "files": [
- "bootstrap.php"
- ],
"psr-4": {
- "voku\\": "src/voku/"
- }
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "(Apache-2.0 or GPL-2.0)"
+ "MIT"
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Hamid Sarfraz",
- "homepage": "http://pageconfig.com/"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
- "name": "Lars Moelleken",
- "homepage": "http://www.moelleken.org/"
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Portable UTF-8 library - performance optimized (unicode) string functions for php.",
- "homepage": "https://github.com/voku/portable-utf8",
- "keywords": [
- "UTF",
- "clean",
- "php",
- "unicode",
- "utf-8",
- "utf8"
- ],
+ "description": "Loads and dumps YAML files",
+ "homepage": "https://symfony.com",
"support": {
- "issues": "https://github.com/voku/portable-utf8/issues",
- "source": "https://github.com/voku/portable-utf8/tree/6.0.13"
+ "source": "https://github.com/symfony/yaml/tree/v7.4.14"
},
"funding": [
{
- "url": "https://www.paypal.me/moelleken",
+ "url": "https://symfony.com/sponsor",
"type": "custom"
},
{
- "url": "https://github.com/voku",
+ "url": "https://github.com/fabpot",
"type": "github"
},
{
- "url": "https://opencollective.com/portable-utf8",
- "type": "open_collective"
- },
- {
- "url": "https://www.patreon.com/voku",
- "type": "patreon"
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/voku/portable-utf8",
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2023-03-08T08:35:38+00:00"
+ "time": "2026-06-08T20:24:16+00:00"
},
{
- "name": "voku/stop-words",
- "version": "2.0.1",
+ "name": "theiconic/name-parser",
+ "version": "v1.2.11",
"source": {
"type": "git",
- "url": "https://github.com/voku/stop-words.git",
- "reference": "8e63c0af20f800b1600783764e0ce19e53969f71"
+ "url": "https://github.com/theiconic/name-parser.git",
+ "reference": "9a54a713bf5b2e7fd990828147d42de16bf8a253"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/voku/stop-words/zipball/8e63c0af20f800b1600783764e0ce19e53969f71",
- "reference": "8e63c0af20f800b1600783764e0ce19e53969f71",
+ "url": "https://api.github.com/repos/theiconic/name-parser/zipball/9a54a713bf5b2e7fd990828147d42de16bf8a253",
+ "reference": "9a54a713bf5b2e7fd990828147d42de16bf8a253",
"shasum": ""
},
"require": {
- "php": ">=7.0.0"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "~6.0"
+ "php-coveralls/php-coveralls": "^2.1",
+ "php-mock/php-mock-phpunit": "^2.1",
+ "phpunit/phpunit": "^7.0"
},
"type": "library",
"autoload": {
"psr-4": {
- "voku\\": "src/voku/"
+ "TheIconic\\NameParser\\": [
+ "src/",
+ "tests/"
+ ]
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -6759,177 +8829,116 @@
],
"authors": [
{
- "name": "Lars Moelleken",
- "homepage": "http://www.moelleken.org/"
+ "name": "The Iconic",
+ "email": "engineering@theiconic.com.au"
}
],
- "description": "Stop-Words via PHP",
- "keywords": [
- "stop words",
- "stop-words"
- ],
+ "description": "PHP library for parsing a string containing a full name into its parts",
"support": {
- "issues": "https://github.com/voku/stop-words/issues",
- "source": "https://github.com/voku/stop-words/tree/master"
+ "issues": "https://github.com/theiconic/name-parser/issues",
+ "source": "https://github.com/theiconic/name-parser/tree/v1.2.11"
},
- "time": "2018-11-23T01:37:27+00:00"
+ "time": "2019-11-14T14:08:48+00:00"
},
{
- "name": "voku/stringy",
- "version": "6.5.3",
+ "name": "theseer/tokenizer",
+ "version": "1.3.1",
"source": {
"type": "git",
- "url": "https://github.com/voku/Stringy.git",
- "reference": "c453c88fbff298f042c836ef44306f8703b2d537"
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "b7489ce515e168639d17feec34b8847c326b0b3c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/voku/Stringy/zipball/c453c88fbff298f042c836ef44306f8703b2d537",
- "reference": "c453c88fbff298f042c836ef44306f8703b2d537",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c",
+ "reference": "b7489ce515e168639d17feec34b8847c326b0b3c",
"shasum": ""
},
"require": {
- "defuse/php-encryption": "~2.0",
- "ext-json": "*",
- "php": ">=7.0.0",
- "voku/anti-xss": "~4.1",
- "voku/arrayy": "~7.8",
- "voku/email-check": "~3.1",
- "voku/portable-ascii": "~2.0",
- "voku/portable-utf8": "~6.0",
- "voku/urlify": "~5.0"
- },
- "replace": {
- "danielstjules/stringy": "~3.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0"
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"autoload": {
- "files": [
- "src/Create.php"
- ],
- "psr-4": {
- "Stringy\\": "src/"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Daniel St. Jules",
- "email": "danielst.jules@gmail.com",
- "homepage": "http://www.danielstjules.com",
- "role": "Maintainer"
- },
- {
- "name": "Lars Moelleken",
- "email": "lars@moelleken.org",
- "homepage": "https://www.moelleken.org/",
- "role": "Fork-Maintainer"
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
}
],
- "description": "A string manipulation library with multibyte support",
- "homepage": "https://github.com/danielstjules/Stringy",
- "keywords": [
- "UTF",
- "helpers",
- "manipulation",
- "methods",
- "multibyte",
- "string",
- "utf-8",
- "utility",
- "utils"
- ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
- "issues": "https://github.com/voku/Stringy/issues",
- "source": "https://github.com/voku/Stringy"
+ "issues": "https://github.com/theseer/tokenizer/issues",
+ "source": "https://github.com/theseer/tokenizer/tree/1.3.1"
},
"funding": [
{
- "url": "https://www.paypal.me/moelleken",
- "type": "custom"
- },
- {
- "url": "https://github.com/voku",
+ "url": "https://github.com/theseer",
"type": "github"
- },
- {
- "url": "https://www.patreon.com/voku",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/voku/stringy",
- "type": "tidelift"
}
],
- "time": "2022-03-28T14:52:20+00:00"
+ "time": "2025-11-17T20:03:58+00:00"
},
{
- "name": "voku/urlify",
- "version": "5.0.7",
+ "name": "voku/portable-ascii",
+ "version": "2.0.3",
"source": {
"type": "git",
- "url": "https://github.com/voku/urlify.git",
- "reference": "014b2074407b5db5968f836c27d8731934b330e4"
+ "url": "https://github.com/voku/portable-ascii.git",
+ "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/voku/urlify/zipball/014b2074407b5db5968f836c27d8731934b330e4",
- "reference": "014b2074407b5db5968f836c27d8731934b330e4",
+ "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d",
+ "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d",
"shasum": ""
},
"require": {
- "php": ">=7.0.0",
- "voku/portable-ascii": "~2.0",
- "voku/portable-utf8": "~6.0",
- "voku/stop-words": "~2.0"
+ "php": ">=7.0.0"
},
"require-dev": {
"phpunit/phpunit": "~6.0 || ~7.0 || ~9.0"
},
+ "suggest": {
+ "ext-intl": "Use Intl for transliterator_transliterate() support"
+ },
"type": "library",
"autoload": {
"psr-4": {
- "voku\\helper\\": "src/voku/helper/"
+ "voku\\": "src/voku/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
- {
- "name": "Johnny Broadway",
- "email": "johnny@johnnybroadway.com",
- "homepage": "http://www.johnnybroadway.com/"
- },
{
"name": "Lars Moelleken",
- "email": "lars@moelleken.org",
- "homepage": "https://moelleken.org/"
+ "homepage": "https://www.moelleken.org/"
}
],
- "description": "PHP port of URLify.js from the Django project. Transliterates non-ascii characters for use in URLs.",
- "homepage": "https://github.com/voku/urlify",
+ "description": "Portable ASCII library - performance optimized (ascii) string functions for php.",
+ "homepage": "https://github.com/voku/portable-ascii",
"keywords": [
- "encode",
- "iconv",
- "link",
- "slug",
- "translit",
- "transliterate",
- "transliteration",
- "url",
- "urlify"
+ "ascii",
+ "clean",
+ "php"
],
"support": {
- "issues": "https://github.com/voku/urlify/issues",
- "source": "https://github.com/voku/urlify/tree/5.0.7"
+ "issues": "https://github.com/voku/portable-ascii/issues",
+ "source": "https://github.com/voku/portable-ascii/tree/2.0.3"
},
"funding": [
{
@@ -6940,56 +8949,49 @@
"url": "https://github.com/voku",
"type": "github"
},
+ {
+ "url": "https://opencollective.com/portable-ascii",
+ "type": "open_collective"
+ },
{
"url": "https://www.patreon.com/voku",
"type": "patreon"
},
{
- "url": "https://tidelift.com/funding/github/packagist/voku/urlify",
+ "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii",
"type": "tidelift"
}
],
- "time": "2022-01-24T19:08:46+00:00"
+ "time": "2024-11-21T01:49:47+00:00"
},
{
"name": "web-auth/cose-lib",
- "version": "4.4.2",
+ "version": "4.5.2",
"source": {
"type": "git",
"url": "https://github.com/web-auth/cose-lib.git",
- "reference": "a93b61c48fb587855f64a9ec11ad7b60e867cb15"
+ "reference": "5b38660f90070a8e45f3dbc9528ade3b608dd77d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/web-auth/cose-lib/zipball/a93b61c48fb587855f64a9ec11ad7b60e867cb15",
- "reference": "a93b61c48fb587855f64a9ec11ad7b60e867cb15",
+ "url": "https://api.github.com/repos/web-auth/cose-lib/zipball/5b38660f90070a8e45f3dbc9528ade3b608dd77d",
+ "reference": "5b38660f90070a8e45f3dbc9528ade3b608dd77d",
"shasum": ""
},
"require": {
- "brick/math": "^0.9|^0.10|^0.11|^0.12|^0.13",
+ "brick/math": "^0.9|^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17",
"ext-json": "*",
"ext-openssl": "*",
"php": ">=8.1",
"spomky-labs/pki-framework": "^1.0"
},
"require-dev": {
- "deptrac/deptrac": "^3.0",
- "ekino/phpstan-banned-code": "^1.0|^2.0|^3.0",
- "infection/infection": "^0.29",
- "php-parallel-lint/php-parallel-lint": "^1.3",
- "phpstan/extension-installer": "^1.3",
- "phpstan/phpstan": "^1.7|^2.0",
- "phpstan/phpstan-deprecation-rules": "^1.0|^2.0",
- "phpstan/phpstan-phpunit": "^1.1|^2.0",
- "phpstan/phpstan-strict-rules": "^1.0|^2.0",
- "phpunit/phpunit": "^10.1|^11.0|^12.0",
- "rector/rector": "^2.0",
- "symfony/phpunit-bridge": "^6.4|^7.0",
- "symplify/easy-coding-standard": "^12.0"
+ "spomky-labs/cbor-php": "^3.2.2"
},
"suggest": {
"ext-bcmath": "For better performance, please install either GMP (recommended) or BCMath extension",
- "ext-gmp": "For better performance, please install either GMP (recommended) or BCMath extension"
+ "ext-gmp": "For better performance, please install either GMP (recommended) or BCMath extension",
+ "spomky-labs/cbor-php": "For COSE Signature support"
},
"type": "library",
"autoload": {
@@ -7019,7 +9021,7 @@
],
"support": {
"issues": "https://github.com/web-auth/cose-lib/issues",
- "source": "https://github.com/web-auth/cose-lib/tree/4.4.2"
+ "source": "https://github.com/web-auth/cose-lib/tree/4.5.2"
},
"funding": [
{
@@ -7031,48 +9033,44 @@
"type": "patreon"
}
],
- "time": "2025-08-14T20:33:29+00:00"
+ "time": "2026-05-03T09:49:50+00:00"
},
{
"name": "web-auth/webauthn-lib",
- "version": "4.9.2",
+ "version": "5.2.6",
"source": {
"type": "git",
"url": "https://github.com/web-auth/webauthn-lib.git",
- "reference": "008b25171c27cf4813420d0de31cc059bcc71f1a"
+ "reference": "0785f55f242c1cc026ec24a9c8653eac59fe3493"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/008b25171c27cf4813420d0de31cc059bcc71f1a",
- "reference": "008b25171c27cf4813420d0de31cc059bcc71f1a",
+ "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/0785f55f242c1cc026ec24a9c8653eac59fe3493",
+ "reference": "0785f55f242c1cc026ec24a9c8653eac59fe3493",
"shasum": ""
},
"require": {
"ext-json": "*",
- "ext-mbstring": "*",
"ext-openssl": "*",
- "lcobucci/clock": "^2.2|^3.0",
"paragonie/constant_time_encoding": "^2.6|^3.0",
- "php": ">=8.1",
+ "php": ">=8.2",
+ "phpdocumentor/reflection-docblock": "^5.3",
"psr/clock": "^1.0",
"psr/event-dispatcher": "^1.0",
- "psr/http-client": "^1.0",
- "psr/http-factory": "^1.0",
"psr/log": "^1.0|^2.0|^3.0",
"spomky-labs/cbor-php": "^3.0",
"spomky-labs/pki-framework": "^1.0",
+ "symfony/clock": "^6.4|^7.0",
"symfony/deprecation-contracts": "^3.2",
- "symfony/uid": "^6.1|^7.0",
+ "symfony/property-access": "^6.4|^7.0",
+ "symfony/property-info": "^6.4|^7.0",
+ "symfony/serializer": "^6.4|^7.0",
+ "symfony/uid": "^6.4|^7.0",
"web-auth/cose-lib": "^4.2.3"
},
"suggest": {
- "phpdocumentor/reflection-docblock": "As of 4.5.x, the phpdocumentor/reflection-docblock component will become mandatory for converting objects such as the Metadata Statement",
- "psr/clock-implementation": "As of 4.5.x, the PSR Clock implementation will replace lcobucci/clock",
"psr/log-implementation": "Recommended to receive logs from the library",
"symfony/event-dispatcher": "Recommended to use dispatched events",
- "symfony/property-access": "As of 4.5.x, the symfony/serializer component will become mandatory for converting objects such as the Metadata Statement",
- "symfony/property-info": "As of 4.5.x, the symfony/serializer component will become mandatory for converting objects such as the Metadata Statement",
- "symfony/serializer": "As of 4.5.x, the symfony/serializer component will become mandatory for converting objects such as the Metadata Statement",
"web-token/jwt-library": "Mandatory for fetching Metadata Statement from distant sources"
},
"type": "library",
@@ -7109,7 +9107,7 @@
"webauthn"
],
"support": {
- "source": "https://github.com/web-auth/webauthn-lib/tree/4.9.2"
+ "source": "https://github.com/web-auth/webauthn-lib/tree/5.2.6"
},
"funding": [
{
@@ -7121,27 +9119,27 @@
"type": "patreon"
}
],
- "time": "2025-01-04T09:47:58+00:00"
+ "time": "2026-03-23T22:13:50+00:00"
},
{
"name": "webmozart/assert",
- "version": "1.12.1",
+ "version": "2.4.1",
"source": {
"type": "git",
"url": "https://github.com/webmozarts/assert.git",
- "reference": "9be6926d8b485f55b9229203f962b51ed377ba68"
+ "reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68",
- "reference": "9be6926d8b485f55b9229203f962b51ed377ba68",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/2ccb7c2e821038c03a3e6e1700c570c158c55f70",
+ "reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-date": "*",
"ext-filter": "*",
- "php": "^7.2 || ^8.0"
+ "php": "^8.2"
},
"suggest": {
"ext-intl": "",
@@ -7150,8 +9148,12 @@
},
"type": "library",
"extra": {
+ "psalm": {
+ "pluginClass": "Webmozart\\Assert\\PsalmPlugin"
+ },
"branch-alias": {
- "dev-master": "1.10-dev"
+ "dev-master": "2.0-dev",
+ "dev-feature/2-0": "2.0-dev"
}
},
"autoload": {
@@ -7167,6 +9169,10 @@
{
"name": "Bernhard Schussek",
"email": "bschussek@gmail.com"
+ },
+ {
+ "name": "Woody Gilk",
+ "email": "woody.gilk@gmail.com"
}
],
"description": "Assertions to validate method input/output with nice error messages.",
@@ -7177,100 +9183,35 @@
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
- "source": "https://github.com/webmozarts/assert/tree/1.12.1"
- },
- "time": "2025-10-29T15:56:20+00:00"
- },
- {
- "name": "webonyx/graphql-php",
- "version": "v14.11.10",
- "source": {
- "type": "git",
- "url": "https://github.com/webonyx/graphql-php.git",
- "reference": "d9c2fdebc6aa01d831bc2969da00e8588cffef19"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/d9c2fdebc6aa01d831bc2969da00e8588cffef19",
- "reference": "d9c2fdebc6aa01d831bc2969da00e8588cffef19",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "ext-mbstring": "*",
- "php": "^7.1 || ^8"
- },
- "require-dev": {
- "amphp/amp": "^2.3",
- "doctrine/coding-standard": "^6.0",
- "nyholm/psr7": "^1.2",
- "phpbench/phpbench": "^1.2",
- "phpstan/extension-installer": "^1.0",
- "phpstan/phpstan": "0.12.82",
- "phpstan/phpstan-phpunit": "0.12.18",
- "phpstan/phpstan-strict-rules": "0.12.9",
- "phpunit/phpunit": "^7.2 || ^8.5",
- "psr/http-message": "^1.0",
- "react/promise": "2.*",
- "simpod/php-coveralls-mirror": "^3.0"
- },
- "suggest": {
- "psr/http-message": "To use standard GraphQL server",
- "react/promise": "To leverage async resolving on React PHP platform"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "GraphQL\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "A PHP port of GraphQL reference implementation",
- "homepage": "https://github.com/webonyx/graphql-php",
- "keywords": [
- "api",
- "graphql"
- ],
- "support": {
- "issues": "https://github.com/webonyx/graphql-php/issues",
- "source": "https://github.com/webonyx/graphql-php/tree/v14.11.10"
+ "source": "https://github.com/webmozarts/assert/tree/2.4.1"
},
- "funding": [
- {
- "url": "https://opencollective.com/webonyx-graphql-php",
- "type": "open_collective"
- }
- ],
- "time": "2023-07-05T14:23:37+00:00"
+ "time": "2026-06-15T15:31:57+00:00"
},
{
"name": "yiisoft/yii2",
- "version": "2.0.52",
+ "version": "2.0.55",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-framework.git",
- "reference": "540e7387d934c52e415614aa081fb38d04c72d9a"
+ "reference": "b900eecdb225041a4c4e0f5e0e5336f606a23bdb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/540e7387d934c52e415614aa081fb38d04c72d9a",
- "reference": "540e7387d934c52e415614aa081fb38d04c72d9a",
+ "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/b900eecdb225041a4c4e0f5e0e5336f606a23bdb",
+ "reference": "b900eecdb225041a4c4e0f5e0e5336f606a23bdb",
"shasum": ""
},
"require": {
"bower-asset/inputmask": "^5.0.8 ",
"bower-asset/jquery": "3.7.*@stable | 3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
- "bower-asset/punycode": "^1.4",
+ "bower-asset/punycode": "^2.2",
"bower-asset/yii2-pjax": "~2.0.1",
"cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0",
"ext-ctype": "*",
"ext-mbstring": "*",
"ezyang/htmlpurifier": "^4.17",
"lib-pcre": "*",
- "php": ">=7.3.0",
+ "php": ">=7.4.0",
"yiisoft/yii2-composer": "~2.0.4"
},
"bin": [
@@ -7365,7 +9306,7 @@
"type": "tidelift"
}
],
- "time": "2025-02-13T20:02:28+00:00"
+ "time": "2026-05-09T14:50:57+00:00"
},
{
"name": "yiisoft/yii2-composer",
@@ -7536,16 +9477,16 @@
},
{
"name": "yiisoft/yii2-queue",
- "version": "2.3.7",
+ "version": "2.3.8",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-queue.git",
- "reference": "dbc9d4a7b2a6995cd19c3e334227482ef55e559b"
+ "reference": "e0f935e5b868d53347acfb14ec19faaf16085005"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/yiisoft/yii2-queue/zipball/dbc9d4a7b2a6995cd19c3e334227482ef55e559b",
- "reference": "dbc9d4a7b2a6995cd19c3e334227482ef55e559b",
+ "url": "https://api.github.com/repos/yiisoft/yii2-queue/zipball/e0f935e5b868d53347acfb14ec19faaf16085005",
+ "reference": "e0f935e5b868d53347acfb14ec19faaf16085005",
"shasum": ""
},
"require": {
@@ -7557,14 +9498,14 @@
"aws/aws-sdk-php": ">=2.4",
"cweagans/composer-patches": "^1.7",
"enqueue/amqp-lib": "^0.8||^0.9.10||^0.10.0",
- "enqueue/stomp": "^0.8.39||^0.10.0",
+ "enqueue/stomp": "^0.8.39||0.10.19",
"opis/closure": "*",
"pda/pheanstalk": "~3.2.1",
"php-amqplib/php-amqplib": "^2.8.0||^3.0.0",
"phpunit/phpunit": "4.8.34",
"yiisoft/yii2-debug": "~2.1.0",
"yiisoft/yii2-gii": "~2.2.0",
- "yiisoft/yii2-redis": "~2.0.0"
+ "yiisoft/yii2-redis": "2.0.19"
},
"suggest": {
"aws/aws-sdk-php": "Need for aws SQS.",
@@ -7617,7 +9558,7 @@
"email": "zhuravljov@gmail.com"
}
],
- "description": "Yii2 Queue Extension which supported DB, Redis, RabbitMQ, Beanstalk, SQS and Gearman",
+ "description": "Yii2 Queue Extension which supports queues based on DB, Redis, RabbitMQ, Beanstalk, SQS, and Gearman",
"keywords": [
"async",
"beanstalk",
@@ -7649,7 +9590,7 @@
"type": "tidelift"
}
],
- "time": "2024-04-29T09:40:52+00:00"
+ "time": "2026-01-08T07:52:05+00:00"
},
{
"name": "yiisoft/yii2-symfonymailer",
diff --git a/extension.neon b/extension.neon
index 4d2b4bb..785f8b6 100644
--- a/extension.neon
+++ b/extension.neon
@@ -7,8 +7,25 @@ parameters:
- %currentWorkingDirectory%/modules
- %currentWorkingDirectory%/plugins
handleMap: []
+ craftTemplateScan:
+ # Directory names (not paths) pruned from the template walk. Keeps
+ # third-party templates bundled under vendor/ (Craft's own CP templates,
+ # other plugins' example/asset templates) out of scanning when a
+ # template path points at a directory that contains them.
+ excludeDirectories:
+ - vendor
+ - node_modules
craftcms:
projectConfigPath: %currentWorkingDirectory%/config/project
+ craftTwigPerformance:
+ enabled: true
+ templatePaths: %craftActionInput.templatePaths%
+ checks:
+ nPlusOne: true
+ nestedRelationAll: true
+ queryInLoop: true
+ lengthOnQuery: true
+ unboundedAll: false
reportUnmatchedIgnoredErrors: false
excludePaths:
- ../../craftcms/cms/src/test/internal/*
@@ -45,9 +62,23 @@ parametersSchema:
templatePaths: listOf(string())
handleMap: schema(arrayOf(string()))
])
+ craftTemplateScan: structure([
+ excludeDirectories: listOf(string())
+ ])
craftcms: structure([
projectConfigPath: schema(string())
])
+ craftTwigPerformance: structure([
+ enabled: schema(bool())
+ templatePaths: listOf(string())
+ checks: structure([
+ nPlusOne: schema(bool())
+ nestedRelationAll: schema(bool())
+ queryInLoop: schema(bool())
+ lengthOnQuery: schema(bool())
+ unboundedAll: schema(bool())
+ ])
+ ])
services:
-
@@ -68,10 +99,27 @@ services:
class: Jensderond\PhpstanCraftcms\Collector\ControllerActionCollector
tags:
- phpstan.collector
+ -
+ class: Jensderond\PhpstanCraftcms\Collector\AnalysisMarkerCollector
+ tags:
+ - phpstan.collector
+ -
+ class: Jensderond\PhpstanCraftcms\Twig\TwigTemplateScanner
+ arguments:
+ parser: @Jensderond\PhpstanCraftcms\Twig\TwigTemplateParser
+ actionInputPaths: %craftActionInput.templatePaths%
+ performancePaths: %craftTwigPerformance.templatePaths%
+ excludeDirectories: %craftTemplateScan.excludeDirectories%
+ -
+ class: Jensderond\PhpstanCraftcms\Twig\TwigTemplateCacheMetaExtension
+ arguments:
+ scanner: @Jensderond\PhpstanCraftcms\Twig\TwigTemplateScanner
+ tags:
+ - phpstan.resultCacheMetaExtension
-
class: Jensderond\PhpstanCraftcms\Rule\TwigActionInputRule
arguments:
- templatePaths: %craftActionInput.templatePaths%
+ scanner: @Jensderond\PhpstanCraftcms\Twig\TwigTemplateScanner
tags:
- phpstan.rules.rule
-
@@ -86,3 +134,18 @@ services:
class: Jensderond\PhpstanCraftcms\Reflection\CustomFieldQueryMethodsExtension
tags:
- phpstan.broker.methodsClassReflectionExtension
+ - Jensderond\PhpstanCraftcms\Twig\TwigTemplateParser
+ - Jensderond\PhpstanCraftcms\Helper\RelationFieldRegistry(%craftcms.projectConfigPath%)
+ -
+ class: Jensderond\PhpstanCraftcms\Twig\TwigPerformanceAnalyzer
+ arguments:
+ relations: @Jensderond\PhpstanCraftcms\Helper\RelationFieldRegistry
+ enabledChecks: %craftTwigPerformance.checks%
+ -
+ class: Jensderond\PhpstanCraftcms\Rule\TwigPerformanceRule
+ arguments:
+ scanner: @Jensderond\PhpstanCraftcms\Twig\TwigTemplateScanner
+ analyzer: @Jensderond\PhpstanCraftcms\Twig\TwigPerformanceAnalyzer
+ enabled: %craftTwigPerformance.enabled%
+ tags:
+ - phpstan.rules.rule
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..5c8474e
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,13 @@
+
+
+
+
+ tests
+
+
+
diff --git a/src/Collector/AnalysisMarkerCollector.php b/src/Collector/AnalysisMarkerCollector.php
new file mode 100644
index 0000000..96b2d27
--- /dev/null
+++ b/src/Collector/AnalysisMarkerCollector.php
@@ -0,0 +1,41 @@
+
+ */
+final class AnalysisMarkerCollector implements Collector
+{
+ public function getNodeType(): string
+ {
+ return FileNode::class;
+ }
+
+ /**
+ * @param FileNode $node
+ */
+ public function processNode(Node $node, Scope $scope): bool
+ {
+ return true;
+ }
+}
diff --git a/src/Helper/RelationFieldRegistry.php b/src/Helper/RelationFieldRegistry.php
new file mode 100644
index 0000000..f69d6c5
--- /dev/null
+++ b/src/Helper/RelationFieldRegistry.php
@@ -0,0 +1,99 @@
+
+ */
+ private const RELATIONAL_FIELD_TYPES = [
+ 'craft\\fields\\Entries',
+ 'craft\\fields\\Categories',
+ 'craft\\fields\\Assets',
+ 'craft\\fields\\Users',
+ 'craft\\fields\\Tags',
+ 'craft\\fields\\Matrix',
+ 'craft\\fields\\Addresses',
+ ];
+
+ /**
+ * Native element accessors that lazily query related elements.
+ *
+ * @var array
+ */
+ private const BUILT_IN_RELATIONS = [
+ 'author' => true,
+ 'parent' => true,
+ 'children' => true,
+ 'ancestors' => true,
+ 'descendants' => true,
+ 'siblings' => true,
+ 'prevSibling' => true,
+ 'nextSibling' => true,
+ 'currentRevision' => true,
+ ];
+
+ /** @var array|null */
+ private ?array $relationHandles = null;
+
+ public function __construct(private readonly string $projectConfigPath) {}
+
+ public function isRelation(string $handle): bool
+ {
+ if (isset(self::BUILT_IN_RELATIONS[$handle])) {
+ return true;
+ }
+
+ return isset($this->relationalHandles()[$handle]);
+ }
+
+ /**
+ * @return array
+ */
+ private function relationalHandles(): array
+ {
+ if ($this->relationHandles !== null) {
+ return $this->relationHandles;
+ }
+
+ $handles = [];
+ $root = rtrim($this->projectConfigPath, '/');
+
+ foreach (glob($root.'/fields/*.yaml') ?: [] as $file) {
+ $handle = $this->relationalHandleFromFile($file);
+ if ($handle !== null) {
+ $handles[$handle] = true;
+ }
+ }
+
+ return $this->relationHandles = $handles;
+ }
+
+ private function relationalHandleFromFile(string $file): ?string
+ {
+ $contents = @file_get_contents($file);
+ if ($contents === false) {
+ return null;
+ }
+
+ if (preg_match('/^type:\s*(\S+)\s*$/m', $contents, $typeMatch) !== 1) {
+ return null;
+ }
+
+ $type = trim($typeMatch[1], "\"'");
+ if (! in_array($type, self::RELATIONAL_FIELD_TYPES, true)) {
+ return null;
+ }
+
+ if (preg_match('/^handle:\s*(\S+)\s*$/m', $contents, $handleMatch) !== 1) {
+ return null;
+ }
+
+ return trim($handleMatch[1], "\"'");
+ }
+}
diff --git a/src/Rule/TwigActionInputRule.php b/src/Rule/TwigActionInputRule.php
index caeb46d..2265b63 100644
--- a/src/Rule/TwigActionInputRule.php
+++ b/src/Rule/TwigActionInputRule.php
@@ -7,29 +7,28 @@
use Jensderond\PhpstanCraftcms\Collector\ControllerActionCollector;
use Jensderond\PhpstanCraftcms\Helper\ActionRouteMap;
use Jensderond\PhpstanCraftcms\Helper\ActionRouteResolver;
+use Jensderond\PhpstanCraftcms\Twig\TwigTemplateScanner;
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Node\CollectedDataNode;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
-use RecursiveDirectoryIterator;
-use RecursiveIteratorIterator;
-use SplFileInfo;
/**
* Validates that actionInput() calls in Twig templates reference valid controller action routes.
*
+ * Template traversal is delegated to {@see TwigTemplateScanner} (shared with
+ * the performance scanning); this rule only needs each template's raw contents
+ * for its regex match.
+ *
* @implements Rule
*/
final class TwigActionInputRule implements Rule
{
- /**
- * @param list $templatePaths
- */
public function __construct(
private readonly ActionRouteMap $actionRouteMap,
- private readonly array $templatePaths,
+ private readonly TwigTemplateScanner $scanner,
) {}
public function getNodeType(): string
@@ -75,12 +74,14 @@ public function processNode(Node $node, Scope $scope): array
/** @var list $errors */
$errors = [];
- foreach ($this->templatePaths as $templatePath) {
- if (! is_dir($templatePath)) {
+ foreach ($this->scanner->scan() as $template) {
+ $contents = $template->contents();
+
+ if ($contents === null) {
continue;
}
- $this->scanDirectory($templatePath, $validRoutes, $errors);
+ $this->scanTwigFile($template->path(), $contents, $validRoutes, $errors);
}
return $errors;
@@ -90,40 +91,8 @@ public function processNode(Node $node, Scope $scope): array
* @param array $validRoutes
* @param list $errors
*/
- private function scanDirectory(string $directory, array $validRoutes, array &$errors): void
+ private function scanTwigFile(string $filePath, string $contents, array $validRoutes, array &$errors): void
{
- $iterator = new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator($directory),
- );
-
- /** @var SplFileInfo $file */
- foreach ($iterator as $file) {
- if ($file->getExtension() !== 'twig') {
- continue;
- }
-
- $realPath = $file->getRealPath();
-
- if ($realPath === false) {
- continue;
- }
-
- $this->scanTwigFile($realPath, $validRoutes, $errors);
- }
- }
-
- /**
- * @param array $validRoutes
- * @param list $errors
- */
- private function scanTwigFile(string $filePath, array $validRoutes, array &$errors): void
- {
- $contents = file_get_contents($filePath);
-
- if ($contents === false) {
- return;
- }
-
// Match actionInput('route/string') or actionInput("route/string")
if (! preg_match_all('/actionInput\(\s*[\'"]([^\'"]+)[\'"]/m', $contents, $matches, PREG_OFFSET_CAPTURE)) {
return;
diff --git a/src/Rule/TwigPerformanceRule.php b/src/Rule/TwigPerformanceRule.php
new file mode 100644
index 0000000..6ed1b77
--- /dev/null
+++ b/src/Rule/TwigPerformanceRule.php
@@ -0,0 +1,82 @@
+
+ */
+final class TwigPerformanceRule implements Rule
+{
+ public function __construct(
+ private readonly TwigTemplateScanner $scanner,
+ private readonly TwigPerformanceAnalyzer $analyzer,
+ private readonly bool $enabled,
+ ) {}
+
+ public function getNodeType(): string
+ {
+ return CollectedDataNode::class;
+ }
+
+ /**
+ * @param CollectedDataNode $node
+ * @return list
+ */
+ public function processNode(Node $node, Scope $scope): array
+ {
+ return $this->scanTemplates();
+ }
+
+ /**
+ * @return list
+ */
+ public function scanTemplates(): array
+ {
+ if (! $this->enabled) {
+ return [];
+ }
+
+ /** @var list $errors */
+ $errors = [];
+
+ foreach ($this->scanner->scan() as $template) {
+ $module = $template->module();
+ if ($module === null) {
+ continue;
+ }
+
+ foreach ($this->analyzer->analyze($module) as $finding) {
+ $builder = RuleErrorBuilder::message($finding->message)
+ ->file($template->path())
+ ->line($finding->line)
+ ->identifier($finding->identifier);
+
+ if ($finding->tip !== null) {
+ $builder->tip($finding->tip);
+ }
+
+ $errors[] = $builder->build();
+ }
+ }
+
+ return $errors;
+ }
+}
diff --git a/src/Twig/Finding.php b/src/Twig/Finding.php
new file mode 100644
index 0000000..a2828da
--- /dev/null
+++ b/src/Twig/Finding.php
@@ -0,0 +1,15 @@
+parser->getStream();
+
+ // Drop every token of this tag statement until its closing `%}`.
+ while (! $stream->test(Token::BLOCK_END_TYPE)) {
+ $stream->next();
+ }
+ $stream->expect(Token::BLOCK_END_TYPE);
+
+ return new Nodes([], $token->getLine());
+ }
+
+ public function getTag(): string
+ {
+ return $this->tag;
+ }
+}
diff --git a/src/Twig/ScannedTemplate.php b/src/Twig/ScannedTemplate.php
new file mode 100644
index 0000000..f587ed7
--- /dev/null
+++ b/src/Twig/ScannedTemplate.php
@@ -0,0 +1,61 @@
+path;
+ }
+
+ /**
+ * Raw file contents, or null when the file could not be read.
+ */
+ public function contents(): ?string
+ {
+ if ($this->contents === null) {
+ $this->contents = @file_get_contents($this->path);
+ }
+
+ return $this->contents === false ? null : $this->contents;
+ }
+
+ /**
+ * The parsed Twig module, or null when the file could not be read or parsed.
+ */
+ public function module(): ?ModuleNode
+ {
+ if (! $this->parsed) {
+ $this->parsed = true;
+
+ $contents = $this->contents();
+ if ($contents !== null) {
+ $this->module = $this->parser->parseSource($contents, $this->path);
+ }
+ }
+
+ return $this->module;
+ }
+}
diff --git a/src/Twig/TwigNodeHelper.php b/src/Twig/TwigNodeHelper.php
new file mode 100644
index 0000000..1300bdc
--- /dev/null
+++ b/src/Twig/TwigNodeHelper.php
@@ -0,0 +1,245 @@
+hasAttribute('name') && ! $node->hasNode('node')) {
+ $name = $node->getAttribute('name');
+
+ return is_string($name) ? $name : null;
+ }
+
+ return null;
+ }
+
+ /**
+ * The accessor name of a GetAttr node (e.g. `author` in `entry.author`).
+ */
+ public static function attrName(GetAttrExpression $node): ?string
+ {
+ if (! $node->hasNode('attribute')) {
+ return null;
+ }
+
+ $attr = $node->getNode('attribute');
+ if ($attr instanceof ConstantExpression) {
+ $value = $attr->getAttribute('value');
+
+ return is_string($value) ? $value : null;
+ }
+
+ return null;
+ }
+
+ /**
+ * True when the GetAttr is a method call (`foo.bar(...)`) rather than a
+ * property/array access.
+ */
+ public static function isMethodCall(GetAttrExpression $node): bool
+ {
+ return $node->hasAttribute('type') && $node->getAttribute('type') === 'method';
+ }
+
+ /**
+ * Walks a GetAttr/method chain and returns the set of accessor names used,
+ * e.g. for `q.with([...]).all()` → ['with' => true, 'all' => true].
+ *
+ * @return array
+ */
+ public static function methodsInChain(Node $node): array
+ {
+ $methods = [];
+ $current = $node;
+
+ while ($current instanceof GetAttrExpression) {
+ if (self::isMethodCall($current)) {
+ $name = self::attrName($current);
+ if ($name !== null) {
+ $methods[$name] = true;
+ }
+ }
+ $current = $current->hasNode('node') ? $current->getNode('node') : null;
+ if (! $current instanceof Node) {
+ break;
+ }
+ }
+
+ return $methods;
+ }
+
+ /**
+ * For a `with([...])` call somewhere in the chain rooted at $node, return the
+ * literal string relation handles it eager-loads. Returns null when a
+ * `with(...)` exists but its argument is not a literal string array (dynamic
+ * args → caller must treat relations as possibly eager-loaded).
+ *
+ * @return array|null
+ */
+ public static function eagerLoadedRelations(Node $node): ?array
+ {
+ $current = $node;
+
+ while ($current instanceof GetAttrExpression) {
+ if (self::isMethodCall($current) && self::attrName($current) === 'with' && $current->hasNode('arguments')) {
+ return self::literalStringsFromArguments($current->getNode('arguments'));
+ }
+ $current = $current->hasNode('node') ? $current->getNode('node') : null;
+ if (! $current instanceof Node) {
+ break;
+ }
+ }
+
+ return [];
+ }
+
+ /**
+ * @return array|null null when args are not a literal string list
+ */
+ private static function literalStringsFromArguments(Node $arguments): ?array
+ {
+ // $arguments is an ArrayExpression of call args: its children alternate
+ // key (a LocalVariable holding the positional index) / value (the actual
+ // argument expression). The first call argument's value is therefore at
+ // index 1, not index 0.
+ $first = self::firstArgumentValue($arguments);
+
+ if ($first instanceof ConstantExpression) {
+ $value = $first->getAttribute('value');
+
+ return is_string($value) ? [$value => true] : null;
+ }
+
+ if ($first instanceof ArrayExpression) {
+ $relations = [];
+ foreach ($first->getKeyValuePairs() as $pair) {
+ $element = $pair['value'];
+ if (! $element instanceof ConstantExpression) {
+ return null; // dynamic element → unknown
+ }
+ $value = $element->getAttribute('value');
+ if (is_string($value)) {
+ $relations[$value] = true;
+ }
+ }
+
+ return $relations;
+ }
+
+ return null; // not a literal → unknown
+ }
+
+ private static function firstArgumentValue(Node $arguments): ?Node
+ {
+ if ($arguments instanceof ArrayExpression) {
+ $pairs = $arguments->getKeyValuePairs();
+
+ return $pairs === [] ? null : $pairs[0]['value'];
+ }
+
+ foreach ($arguments as $arg) {
+ return $arg;
+ }
+
+ return null;
+ }
+
+ /**
+ * Root variable name of a GetAttr/method chain, e.g. `craft` in
+ * `craft.entries.all()`.
+ */
+ public static function rootName(Node $node): ?string
+ {
+ $current = $node;
+ while ($current instanceof GetAttrExpression && $current->hasNode('node')) {
+ $current = $current->getNode('node');
+ }
+
+ return self::nameOf($current);
+ }
+
+ /**
+ * Heuristic: the chain looks like a Craft element query (`craft.entries`,
+ * `craft.assets`, ... or a `.find()`/`.relatedTo()` builder).
+ */
+ public static function isQueryRooted(Node $node): bool
+ {
+ if (self::rootName($node) === 'craft') {
+ return self::chainHasAnyAttr($node, ['entries', 'assets', 'users', 'categories', 'tags', 'addresses']);
+ }
+
+ $methods = self::methodsInChain($node);
+
+ return isset($methods['find']) || isset($methods['relatedTo']);
+ }
+
+ /**
+ * @param list $names
+ */
+ public static function chainHasAnyAttr(Node $node, array $names): bool
+ {
+ foreach ($names as $name) {
+ if (self::chainHasAttr($node, $name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static function chainHasAttr(Node $node, string $name): bool
+ {
+ $current = $node;
+ while ($current instanceof GetAttrExpression) {
+ if (self::attrName($current) === $name) {
+ return true;
+ }
+ $current = $current->hasNode('node') ? $current->getNode('node') : null;
+ if (! $current instanceof Node) {
+ break;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * The filter name of a FilterExpression (e.g. `length` in `foo|length`).
+ * Verified against Twig 3.27 (the required floor): the `name` attribute is
+ * always set by the FilterExpression constructor regardless of how it was
+ * built, and the `filter` child node (when present) is a ConstantExpression
+ * carrying the same value.
+ */
+ public static function filterName(FilterExpression $node): ?string
+ {
+ if ($node->hasAttribute('name')) {
+ $name = $node->getAttribute('name');
+
+ return is_string($name) ? $name : null;
+ }
+
+ if ($node->hasNode('filter')) {
+ $filter = $node->getNode('filter');
+ if ($filter instanceof ConstantExpression) {
+ $value = $filter->getAttribute('value');
+
+ return is_string($value) ? $value : null;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/src/Twig/TwigPerformanceAnalyzer.php b/src/Twig/TwigPerformanceAnalyzer.php
new file mode 100644
index 0000000..1fb7c48
--- /dev/null
+++ b/src/Twig/TwigPerformanceAnalyzer.php
@@ -0,0 +1,737 @@
+ */
+ private array $findings = [];
+
+ /**
+ * Stack of active loops. Each frame: loop value-variable name + the relations
+ * known to be eager-loaded on the loop source. eagerLoaded === null means a
+ * dynamic with(...) was present → suppress N+1 for this loop. nonElement is
+ * true when the loop iterates a plain data structure (an array/hash literal,
+ * directly or via {% set %}/nesting) rather than element query results — such
+ * a loop variable can never trigger a relation N+1, so those checks skip it.
+ *
+ * @var list|null, nonElement: bool}>
+ */
+ private array $loopStack = [];
+
+ /**
+ * Variables assigned in the current scope via {% set x = ... %}, mapped to
+ * the assigned expression, so a loop over `x` can resolve its source.
+ *
+ * @var array
+ */
+ private array $assignments = [];
+
+ /**
+ * Variable names currently bound to a plain (non-element) value: assigned an
+ * array/hash literal via {% set %}, or the value variable of a loop whose
+ * source is itself plain. Used to propagate "this is not a Craft element"
+ * through {% set %} and nested loops (e.g. the fonts hash in
+ * `{% for family, fonts in fonts %}{% for font in fonts %}`).
+ *
+ * @var array
+ */
+ private array $plainVars = [];
+
+ /**
+ * @param array $enabledChecks
+ */
+ public function __construct(
+ private readonly RelationFieldRegistry $relations,
+ private readonly array $enabledChecks,
+ ) {}
+
+ /**
+ * @return list
+ */
+ public function analyze(ModuleNode $module): array
+ {
+ $this->findings = [];
+ $this->loopStack = [];
+ $this->assignments = [];
+ $this->plainVars = [];
+
+ $this->walk($module);
+
+ return $this->findings;
+ }
+
+ private function enabled(string $check): bool
+ {
+ return $this->enabledChecks[$check] ?? false;
+ }
+
+ private function walk(Node $node): void
+ {
+ if ($node instanceof SetNode) {
+ $this->recordAssignment($node);
+ }
+
+ if ($node instanceof ForNode) {
+ // Walk the loop's source expression in the OUTER context first: a
+ // query used as the loop's own source runs once (before iteration
+ // begins), so it must not be visible to checks like
+ // checkQueryInLoop() as "inside this loop". If that same source
+ // expression is itself nested inside an enclosing loop, the outer
+ // frame is still on the stack at this point, so it is correctly
+ // flagged as running per outer iteration.
+ $seq = $node->getNode('seq');
+ $this->walk($seq);
+
+ $valueVar = $this->enterLoop($node);
+ $nonElement = $this->loopStack[count($this->loopStack) - 1]['nonElement'];
+
+ // Inside the loop body, the value variable holds one iterated item.
+ // If the source is plain, so is each item — propagate that so a
+ // nested loop over this variable is recognised as plain too. Save
+ // and restore any shadowed outer binding.
+ $hadPlain = isset($this->plainVars[$valueVar]);
+ if ($nonElement) {
+ $this->plainVars[$valueVar] = true;
+ } else {
+ unset($this->plainVars[$valueVar]);
+ }
+
+ // The {% else %} branch runs at most once (only when the sequence
+ // is empty), so it is walked OUTSIDE this loop's frame below —
+ // a query there is not a per-iteration query.
+ $else = $node->hasNode('else') ? $node->getNode('else') : null;
+
+ foreach ($node as $child) {
+ if ($child === $seq || $child === $else) {
+ continue;
+ }
+ $this->walk($child);
+ }
+
+ array_pop($this->loopStack);
+ if ($hadPlain) {
+ $this->plainVars[$valueVar] = true;
+ } else {
+ unset($this->plainVars[$valueVar]);
+ }
+
+ if ($else instanceof Node) {
+ $this->walk($else);
+ }
+
+ return;
+ }
+
+ if ($node instanceof GetAttrExpression) {
+ $this->checkChain($node);
+ $this->checkNestedRelationAll($node);
+ $this->checkQueryInLoop($node);
+ $this->checkUnboundedAll($node);
+ $this->walkChainSideBranches($node);
+
+ return;
+ }
+
+ if ($node instanceof FilterExpression) {
+ $this->checkLengthOnQuery($node);
+ }
+
+ foreach ($node as $child) {
+ $this->walk($child);
+ }
+ }
+
+ /**
+ * GetAttr nodes link into a chain via their `node` child (e.g.
+ * `entry.author.eagerly().one()` is four nested GetAttrs). We only want to
+ * evaluate the N+1 check once per chain — from the outermost node, looking
+ * down the whole chain — rather than once per GetAttr in it, otherwise a
+ * `.eagerly()` applied above the relation access would not be visible when
+ * the inner `entry.author` node is inspected in isolation.
+ *
+ * `walk()` only calls this for a GetAttr it reaches by general recursion,
+ * which is always the outermost unvisited GetAttr of its chain (inner ones
+ * are consumed by walkChainSideBranches() below, not by the outer foreach),
+ * so every chain is scanned exactly once, top-down.
+ */
+ private function checkChain(GetAttrExpression $node): void
+ {
+ if (! $this->enabled('nPlusOne') || $this->loopStack === []) {
+ return;
+ }
+
+ $chainMethodsAboveRelation = [];
+ $current = $node;
+
+ while ($current instanceof GetAttrExpression) {
+ $object = $current->hasNode('node') ? $current->getNode('node') : null;
+ $objectName = $object instanceof Node ? TwigNodeHelper::nameOf($object) : null;
+
+ // The chain may be rooted at ANY active loop's value variable, not
+ // just the innermost one: `entry.author` inside a nested loop still
+ // runs once per `entry` iteration. elementLoopFrame() resolves the
+ // name shadow-aware, so an inner loop over a plain literal masks an
+ // outer element loop of the same variable name.
+ if ($objectName !== null && ($frame = $this->elementLoopFrame($objectName)) !== null) {
+ // `.` found: $current is the relation access.
+ $this->reportIfUnguarded($current, $frame, $chainMethodsAboveRelation);
+
+ return;
+ }
+
+ if (TwigNodeHelper::isMethodCall($current)) {
+ $name = TwigNodeHelper::attrName($current);
+ if ($name !== null) {
+ $chainMethodsAboveRelation[$name] = true;
+ }
+ }
+
+ $current = $object;
+ }
+ }
+
+ /**
+ * @param array{var: string, eagerLoaded: array|null} $frame
+ * @param array $methodsAboveRelation Method names applied
+ * on top of the relation access within the same chain, e.g. `eagerly`
+ * in `entry.author.eagerly().one()`.
+ */
+ private function reportIfUnguarded(GetAttrExpression $relationAccess, array $frame, array $methodsAboveRelation): void
+ {
+ if (isset($methodsAboveRelation['eagerly'])) {
+ return;
+ }
+
+ $attr = TwigNodeHelper::attrName($relationAccess);
+ if ($attr === null || ! $this->relations->isRelation($attr)) {
+ return;
+ }
+
+ // Suppress if eager-loaded (or dynamic with(...) → null → unknown).
+ $eager = $frame['eagerLoaded'];
+ if ($eager === null || $this->isEagerLoaded($eager, $attr)) {
+ return;
+ }
+
+ $this->findings[] = new Finding(
+ 'craftcms.twigNPlusOne',
+ $relationAccess->getTemplateLine(),
+ sprintf('Relation "%s" is accessed inside a loop without eager-loading, causing an N+1 query.', $attr),
+ sprintf('Eager-load it on the query with .with([\'%s\']) or use %s.%s.eagerly() in the loop.', $attr, $frame['var'], $attr),
+ );
+ }
+
+ /**
+ * Pattern: `..all()` inside a loop — a nested relation
+ * fetched with .all() on each iteration, causing an N+1 query, unless
+ * `.eagerly()` is also present in the chain (it sits below the terminal
+ * `.all()`, e.g. `entry.rel.eagerly().all()`, so methodsInChain($node) sees it).
+ *
+ * $node is the terminal (outermost) GetAttr of its chain — see walk().
+ */
+ private function checkNestedRelationAll(GetAttrExpression $node): void
+ {
+ if (! $this->enabled('nestedRelationAll') || $this->loopStack === []) {
+ return;
+ }
+
+ if (! TwigNodeHelper::isMethodCall($node) || TwigNodeHelper::attrName($node) !== 'all') {
+ return;
+ }
+
+ $methods = TwigNodeHelper::methodsInChain($node);
+ if (isset($methods['eagerly'])) {
+ return;
+ }
+
+ $object = $node->hasNode('node') ? $node->getNode('node') : null;
+ if (! $object instanceof GetAttrExpression) {
+ return;
+ }
+
+ // Walk down through any method calls to the relation access itself.
+ $relationNode = $object;
+ while ($relationNode instanceof GetAttrExpression && TwigNodeHelper::isMethodCall($relationNode)) {
+ $relationNode = $relationNode->hasNode('node') ? $relationNode->getNode('node') : null;
+ }
+ if (! $relationNode instanceof GetAttrExpression || ! $relationNode->hasNode('node')) {
+ return;
+ }
+
+ $objectName = TwigNodeHelper::nameOf($relationNode->getNode('node'));
+ $attr = TwigNodeHelper::attrName($relationNode);
+ if ($objectName === null || $attr === null) {
+ return;
+ }
+ $frame = $this->elementLoopFrame($objectName);
+ if ($frame === null || ! $this->relations->isRelation($attr)) {
+ return;
+ }
+
+ // If the relation is (or may be) eager-loaded, `..all()` is
+ // served from the eager-loaded cache rather than re-querying, so it is
+ // not an N+1. null = unknown (e.g. the loop element came from outside
+ // this template); see resolveEagerLoaded().
+ $eager = $frame['eagerLoaded'];
+ if ($eager === null || $this->isEagerLoaded($eager, $attr)) {
+ return;
+ }
+
+ $this->findings[] = new Finding(
+ 'craftcms.twigNestedRelationAll',
+ $node->getTemplateLine(),
+ sprintf('Nested relation "%s" is fetched with .all() inside a loop, causing an N+1 query.', $attr),
+ sprintf('Use %s.%s.eagerly().all() or eager-load "%s" on the parent query.', $objectName, $attr, $attr),
+ );
+ }
+
+ /**
+ * Fires once per query (on the chain's outermost node) when that query is
+ * built and executed inside a loop. The terminal fetch method
+ * (all/one/count/exists/nth/ids) may sit anywhere in the chain, not just at
+ * the outermost position — e.g. `craft.entries.section('n').one().title`
+ * reads a property off the fetch, so the outermost node is `.title`, not
+ * `.one()`. We therefore scan the whole chain for a terminal fetch method
+ * rather than requiring $node itself to be one.
+ *
+ * $node is the terminal (outermost) GetAttr of its chain — see walk() —
+ * so this still reports exactly once per chain.
+ */
+ private function checkQueryInLoop(GetAttrExpression $node): void
+ {
+ if (! $this->enabled('queryInLoop') || $this->loopStack === []) {
+ return;
+ }
+
+ $methods = TwigNodeHelper::methodsInChain($node);
+ $terminals = array_intersect_key($methods, array_flip(['all', 'one', 'count', 'exists', 'nth', 'ids']));
+ if ($terminals === []) {
+ return;
+ }
+
+ if (! TwigNodeHelper::isQueryRooted($node)) {
+ return;
+ }
+
+ $this->findings[] = new Finding(
+ 'craftcms.twigQueryInLoop',
+ $node->getTemplateLine(),
+ 'An element query is executed inside a loop, running one query per iteration.',
+ 'Move the query outside the loop and eager-load, or collect IDs and query once.',
+ );
+ }
+
+ /**
+ * Unbounded `.all()` on an element query outside any loop (in-loop queries
+ * are checkQueryInLoop's job) with no `.limit()` anywhere in the chain.
+ *
+ * $node is the terminal (outermost) GetAttr of its chain — see walk().
+ */
+ private function checkUnboundedAll(GetAttrExpression $node): void
+ {
+ if (! $this->enabled('unboundedAll') || $this->loopStack !== []) {
+ return;
+ }
+
+ if (! TwigNodeHelper::isMethodCall($node) || TwigNodeHelper::attrName($node) !== 'all') {
+ return;
+ }
+
+ if (! TwigNodeHelper::isQueryRooted($node)) {
+ return;
+ }
+
+ $methods = TwigNodeHelper::methodsInChain($node);
+ if (isset($methods['limit'])) {
+ return;
+ }
+
+ $this->findings[] = new Finding(
+ 'craftcms.twigUnboundedAll',
+ $node->getTemplateLine(),
+ 'Unbounded .all() on an element query may load a large result set into memory.',
+ 'Add .limit(n) if you do not need every element.',
+ );
+ }
+
+ /**
+ * `|length` applied directly to an element query forces it to fetch every
+ * row just to count them; `.count()` is the cheaper equivalent. Does not
+ * return early: the operand's own GetAttr chain still needs to be walked
+ * by the caller.
+ */
+ private function checkLengthOnQuery(FilterExpression $node): void
+ {
+ if (! $this->enabled('lengthOnQuery')) {
+ return;
+ }
+
+ if (TwigNodeHelper::filterName($node) !== 'length') {
+ return;
+ }
+
+ $operand = $node->hasNode('node') ? $node->getNode('node') : null;
+ if (! $operand instanceof Node || ! TwigNodeHelper::isQueryRooted($operand)) {
+ return;
+ }
+
+ // If .all()/.ids() already executed the query, |length is on an array — fine.
+ $methods = TwigNodeHelper::methodsInChain($operand);
+ if (isset($methods['all']) || isset($methods['ids'])) {
+ return;
+ }
+
+ $this->findings[] = new Finding(
+ 'craftcms.twigLengthOnQuery',
+ $node->getTemplateLine(),
+ 'Using |length on an element query fetches every element just to count them.',
+ 'Use .count() instead of |length.',
+ );
+ }
+
+ /**
+ * The innermost active loop frame whose value variable is $name, provided
+ * that loop iterates elements (not a plain array/hash literal); null when
+ * $name is not a loop variable. The innermost match decides so an inner
+ * loop shadowing $name masks the outer binding: if it iterates a plain
+ * literal, $name holds plain values here and no element frame is returned.
+ *
+ * @return array{var: string, eagerLoaded: array|null, nonElement: bool}|null
+ */
+ private function elementLoopFrame(string $name): ?array
+ {
+ for ($i = count($this->loopStack) - 1; $i >= 0; $i--) {
+ $frame = $this->loopStack[$i];
+ if ($frame['var'] === $name) {
+ return $frame['nonElement'] ? null : $frame;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Walk the non-spine children of a GetAttr chain (the `attribute` and
+ * `arguments` of every node in the chain), since those may contain nested
+ * expressions (e.g. other loops, sub-chains) that still need visiting. The
+ * `node` spine itself is intentionally not re-walked here — checkChain()
+ * already scanned it for the N+1 check, and re-walking it would visit the
+ * same chain's GetAttrs a second time via the general walk() recursion.
+ */
+ private function walkChainSideBranches(GetAttrExpression $node): void
+ {
+ $current = $node;
+
+ while ($current instanceof GetAttrExpression) {
+ if ($current->hasNode('attribute')) {
+ $this->walk($current->getNode('attribute'));
+ }
+ if ($current->hasNode('arguments')) {
+ $this->walk($current->getNode('arguments'));
+ }
+
+ $next = $current->hasNode('node') ? $current->getNode('node') : null;
+ if (! $next instanceof GetAttrExpression) {
+ // Reached the chain root (not a GetAttr, e.g. a NameExpression):
+ // walk it normally since nothing else will.
+ if ($next instanceof Node) {
+ $this->walk($next);
+ }
+
+ return;
+ }
+ $current = $next;
+ }
+ }
+
+ private function recordAssignment(SetNode $node): void
+ {
+ if (! $node->hasNode('names') || ! $node->hasNode('values')) {
+ return;
+ }
+
+ // `names`/`values` are each a `Nodes` wrapper; the single-target case
+ // (the common `{% set x = expr %}`) has exactly one child at index 0.
+ $names = $this->firstChild($node->getNode('names'));
+ $values = $this->firstChild($node->getNode('values'));
+
+ if ($names === null || $values === null) {
+ return;
+ }
+
+ $name = TwigNodeHelper::nameOf($names);
+ if ($name !== null) {
+ $this->assignments[$name] = $values;
+
+ if ($this->isPlainExpr($values)) {
+ $this->plainVars[$name] = true;
+ } else {
+ unset($this->plainVars[$name]);
+ }
+ }
+ }
+
+ /**
+ * A plain (non-element) expression: an array/hash literal, or a bare
+ * reference to a variable already known to be plain. Query builders and
+ * relation accesses are GetAttr chains, so they are never plain.
+ */
+ private function isPlainExpr(Node $node): bool
+ {
+ if ($node instanceof ArrayExpression) {
+ return true;
+ }
+
+ $name = TwigNodeHelper::nameOf($node);
+
+ return $name !== null && isset($this->plainVars[$name]);
+ }
+
+ private function firstChild(Node $wrapper): ?Node
+ {
+ foreach ($wrapper as $child) {
+ return $child instanceof Node ? $child : null;
+ }
+
+ return null;
+ }
+
+ /**
+ * Pushes a loop frame and returns the loop's value-variable name.
+ */
+ private function enterLoop(ForNode $node): string
+ {
+ $valueTarget = $node->getNode('value_target');
+ $varName = $valueTarget->hasAttribute('name') ? (string) $valueTarget->getAttribute('name') : '';
+
+ $source = $node->getNode('seq');
+ $resolved = $this->resolveSource($source);
+
+ $this->loopStack[] = [
+ 'var' => $varName,
+ 'eagerLoaded' => $this->resolveEagerLoaded($resolved),
+ 'nonElement' => $this->isPlainExpr($resolved),
+ ];
+
+ return $varName;
+ }
+
+ /**
+ * If the loop source is a bare variable assigned one level back, use that
+ * expression; otherwise use the source expression as-is. Fallback wrappers
+ * (`query ?? []`, `query ?: []`) are unwrapped to the query on both the
+ * direct source and the resolved assignment.
+ */
+ private function resolveSource(Node $source): Node
+ {
+ $source = $this->unwrapFallback($source);
+
+ $name = TwigNodeHelper::nameOf($source);
+ if ($name !== null && isset($this->assignments[$name])) {
+ return $this->unwrapFallback($this->assignments[$name]);
+ }
+
+ return $source;
+ }
+
+ /**
+ * Unwrap a `query ?? default` / `query ?: default` fallback to the query
+ * side, so the eager-loading on the query is visible. Without this the query
+ * is buried in the fallback node and every relation access on the loop items
+ * is misreported — the exact false positive behind the ubiquitous
+ * `craft.…all() ?? []` navigation idiom.
+ *
+ * The AST shape differs across Twig versions:
+ * - Twig ≥3.16 parses `a ?? b` to a NullCoalesceBinary (`left` = the query);
+ * - `a ?: b` (and `a ?? b` on older Twig) is a ConditionalExpression whose
+ * `expr2` holds the value used when the subject is present — the query.
+ */
+ private function unwrapFallback(Node $source): Node
+ {
+ if ($source instanceof NullCoalesceBinary && $source->hasNode('left')) {
+ return $source->getNode('left');
+ }
+
+ if ($source instanceof ConditionalExpression && $source->hasNode('expr2')) {
+ return $source->getNode('expr2');
+ }
+
+ return $source;
+ }
+
+ /**
+ * The eager-load set for a loop source, or null ("unknown") when the source
+ * cannot be traced to something visible in THIS template.
+ *
+ * PHPStan analyses each template in isolation, so a partial that receives an
+ * already-eager-loaded element across an {% include %}/{% embed %} boundary
+ * (e.g. navigation/node.twig iterating `node.children`, where `nodes` was
+ * fetched with `.with(['children.children'])` in the parent layout) has no
+ * way to see that eager-loading. Assuming "nothing eager-loaded" for such an
+ * externally-supplied variable is exactly what produced N+1 false positives.
+ *
+ * We only trust an *empty* eager-load set when we can actually read the
+ * query's chain: a `craft.*` global (covers `craft.entries()…` and plugin
+ * queries such as `craft.navigation.nodes()…`), a builder recognised by
+ * isQueryRooted (`.find()`/`.relatedTo()`), a `{% set %}` variable, or an
+ * element of an enclosing loop whose own source was known. Otherwise the
+ * state is unknown → null, which the N+1 checks treat as
+ * possibly-eager-loaded and suppress (the same sentinel a dynamic
+ * `with(...)` yields).
+ *
+ * @return array|null
+ */
+ private function resolveEagerLoaded(Node $source): ?array
+ {
+ // A plain array/hash literal (or a var known to hold one): no relations.
+ if ($this->isPlainExpr($source)) {
+ return [];
+ }
+
+ $root = TwigNodeHelper::rootName($source);
+
+ // A chain whose query we can read directly — rooted at the `craft`
+ // global, or a recognised builder. A missing `.with()` here genuinely
+ // means no eager-loading.
+ if ($root === 'craft' || TwigNodeHelper::isQueryRooted($source)) {
+ return TwigNodeHelper::eagerLoadedRelations($source);
+ }
+
+ if ($root === null) {
+ // No identifiable root variable (unusual) → keep the conservative reading.
+ return TwigNodeHelper::eagerLoadedRelations($source);
+ }
+
+ // Rooted at an element of an enclosing loop: if that loop's own eager
+ // state was unknown, so is this one (propagate across nested loops such
+ // as `{% for child in node.children %}` under an external `nodes`).
+ // Otherwise descend the enclosing loop's eager-load paths through the
+ // relation(s) accessed here, so a deep path like
+ // `with(['children.children.children'])` keeps covering each nesting
+ // level (`node.children` → the children collection is still eager-loaded
+ // for `children.children`), while relations beyond the path's depth
+ // remain flagged. An explicit `.with()` on this source overrides the
+ // inherited state.
+ foreach ($this->loopStack as $frame) {
+ if ($frame['var'] === $root) {
+ if ($frame['eagerLoaded'] === null) {
+ return null;
+ }
+
+ if (isset(TwigNodeHelper::methodsInChain($source)['with'])) {
+ return TwigNodeHelper::eagerLoadedRelations($source);
+ }
+
+ return $this->descendEagerPaths(
+ $frame['eagerLoaded'],
+ $this->relationSegments($source),
+ );
+ }
+ }
+
+ // Rooted at a variable assigned locally via {% set %}: visible here.
+ if (isset($this->assignments[$root])) {
+ return TwigNodeHelper::eagerLoadedRelations($source);
+ }
+
+ // Rooted at a variable supplied from outside this template (include
+ // variable, embed context, or global). Its eager-load state is
+ // unknowable here → unknown rather than "none".
+ return null;
+ }
+
+ /**
+ * Whether relation $attr is covered by the eager-load set. Handles nested
+ * paths: `with(['children.children'])` eager-loads `children` (the head
+ * segment) as well as its `children`, so accessing `children` on the loop
+ * items is served from cache. A path matches when $attr is exactly the path
+ * or its first dotted segment.
+ *
+ * @param array $eager
+ */
+ private function isEagerLoaded(array $eager, string $attr): bool
+ {
+ foreach (array_keys($eager) as $path) {
+ if ($path === $attr || str_starts_with($path, $attr.'.')) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * The relation segments accessed on a chain rooted at a loop variable, in
+ * root→outer order: `node.children` → ['children'], `node.parent.children`
+ * → ['parent', 'children']. Method calls (`.all()`, `.eagerly()`) are not
+ * segments and are skipped.
+ *
+ * @return list
+ */
+ private function relationSegments(Node $source): array
+ {
+ $segments = [];
+ $current = $source;
+
+ while ($current instanceof GetAttrExpression) {
+ if (! TwigNodeHelper::isMethodCall($current)) {
+ $attr = TwigNodeHelper::attrName($current);
+ if ($attr !== null) {
+ $segments[] = $attr;
+ }
+ }
+ $current = $current->hasNode('node') ? $current->getNode('node') : null;
+ }
+
+ return array_reverse($segments);
+ }
+
+ /**
+ * Descend an eager-load path set through the given relation segments,
+ * returning the eager state of the collection reached. For each segment,
+ * keep only paths whose head matches it and strip that head; a path with no
+ * remaining tail contributed no deeper eager-loading. Example: descending
+ * {'children.children.children'} through ['children'] yields
+ * {'children.children'}; descending {'children'} through ['children']
+ * yields {} (nothing deeper is eager-loaded, so the next level flags).
+ *
+ * @param array $eager
+ * @param list $segments
+ * @return array
+ */
+ private function descendEagerPaths(array $eager, array $segments): array
+ {
+ $set = $eager;
+
+ foreach ($segments as $segment) {
+ $next = [];
+ foreach (array_keys($set) as $path) {
+ $parts = explode('.', $path);
+ if ($parts[0] === $segment && count($parts) > 1) {
+ $next[implode('.', array_slice($parts, 1))] = true;
+ }
+ }
+ $set = $next;
+ }
+
+ return $set;
+ }
+}
diff --git a/src/Twig/TwigTemplateCacheMetaExtension.php b/src/Twig/TwigTemplateCacheMetaExtension.php
new file mode 100644
index 0000000..fbe1755
--- /dev/null
+++ b/src/Twig/TwigTemplateCacheMetaExtension.php
@@ -0,0 +1,52 @@
+scanner->templateFiles() as $path) {
+ $contents = @file_get_contents($path);
+ // Fold path + content into the digest so edits, additions and
+ // removals all shift the hash. Unreadable files contribute their
+ // path only, so a permission flip is still observed.
+ $parts[] = $path.':'.($contents === false ? '' : hash('xxh128', $contents));
+ }
+
+ return hash('xxh128', implode("\n", $parts));
+ }
+}
diff --git a/src/Twig/TwigTemplateParser.php b/src/Twig/TwigTemplateParser.php
new file mode 100644
index 0000000..4b62a7c
--- /dev/null
+++ b/src/Twig/TwigTemplateParser.php
@@ -0,0 +1,65 @@
+twig = new Environment(new ArrayLoader, [
+ 'cache' => false,
+ 'autoescape' => false,
+ 'strict_variables' => false,
+ 'optimizations' => 0,
+ ]);
+
+ // Any tag we do not model becomes an inert node.
+ $this->twig->registerUndefinedTokenParserCallback(
+ static fn (string $name): GenericTagTokenParser => new GenericTagTokenParser($name),
+ );
+
+ // Any unknown function/filter resolves to a no-op so parsing succeeds.
+ $this->twig->registerUndefinedFunctionCallback(
+ static fn (string $name): TwigFunction => new TwigFunction($name, static fn (): string => ''),
+ );
+ $this->twig->registerUndefinedFilterCallback(
+ static fn (string $name): TwigFilter => new TwigFilter($name, static fn ($v) => $v),
+ );
+ }
+
+ public function parseFile(string $path): ?ModuleNode
+ {
+ $code = @file_get_contents($path);
+ if ($code === false) {
+ return null;
+ }
+
+ return $this->parseSource($code, $path);
+ }
+
+ public function parseSource(string $code, string $name = 'template'): ?ModuleNode
+ {
+ try {
+ return $this->twig->parse($this->twig->tokenize(new Source($code, $name)));
+ } catch (Throwable) {
+ return null;
+ }
+ }
+}
diff --git a/src/Twig/TwigTemplateScanner.php b/src/Twig/TwigTemplateScanner.php
new file mode 100644
index 0000000..8672e97
--- /dev/null
+++ b/src/Twig/TwigTemplateScanner.php
@@ -0,0 +1,126 @@
+ */
+ private readonly array $templatePaths;
+
+ /** @var list */
+ private readonly array $excludeDirectories;
+
+ /**
+ * The action-input and performance configs are separate parameters that
+ * usually — but need not — point at the same directories. Both lists are
+ * merged and de-duplicated here so the tree is walked once and every
+ * consumer sees every configured directory.
+ *
+ * @param list $actionInputPaths
+ * @param list $performancePaths
+ * @param list $excludeDirectories Directory names (not paths)
+ * whose subtrees are skipped, e.g. `vendor`, `node_modules`.
+ * Prunes third-party templates a package bundles under
+ * `vendor/` (Craft's own CP templates, other plugins' assets)
+ * when a template path points at a directory containing them.
+ */
+ public function __construct(
+ private readonly TwigTemplateParser $parser,
+ array $actionInputPaths,
+ array $performancePaths,
+ array $excludeDirectories = [],
+ ) {
+ $merged = [];
+ foreach ([...$actionInputPaths, ...$performancePaths] as $path) {
+ $merged[$path] = true;
+ }
+
+ $this->templatePaths = array_keys($merged);
+ $this->excludeDirectories = array_values($excludeDirectories);
+ }
+
+ /**
+ * Absolute, de-duplicated realpaths of every `.twig` file under the
+ * configured template directories, sorted for a stable order.
+ *
+ * @return list
+ */
+ public function templateFiles(): array
+ {
+ $paths = [];
+
+ foreach ($this->templatePaths as $templatePath) {
+ if (! is_dir($templatePath)) {
+ continue;
+ }
+
+ $directory = new RecursiveDirectoryIterator($templatePath, RecursiveDirectoryIterator::SKIP_DOTS);
+
+ // Prune excluded directories during descent so their subtrees are
+ // never entered — cheaper than filtering matched files afterwards.
+ $filtered = new RecursiveCallbackFilterIterator(
+ $directory,
+ function (SplFileInfo $current): bool {
+ if ($current->isDir()) {
+ return ! in_array($current->getFilename(), $this->excludeDirectories, true);
+ }
+
+ return true;
+ },
+ );
+
+ $iterator = new RecursiveIteratorIterator($filtered);
+
+ /** @var SplFileInfo $file */
+ foreach ($iterator as $file) {
+ if ($file->getExtension() !== 'twig') {
+ continue;
+ }
+
+ $realPath = $file->getRealPath();
+ if ($realPath === false) {
+ continue;
+ }
+
+ $paths[$realPath] = true;
+ }
+ }
+
+ $files = array_keys($paths);
+ sort($files);
+
+ return $files;
+ }
+
+ /**
+ * Every discovered template as a lazily-readable {@see ScannedTemplate}.
+ *
+ * @return Generator
+ */
+ public function scan(): Generator
+ {
+ foreach ($this->templateFiles() as $path) {
+ yield new ScannedTemplate($path, $this->parser);
+ }
+ }
+}
diff --git a/tests/Collector/AnalysisMarkerCollectorTest.php b/tests/Collector/AnalysisMarkerCollectorTest.php
new file mode 100644
index 0000000..2a76186
--- /dev/null
+++ b/tests/Collector/AnalysisMarkerCollectorTest.php
@@ -0,0 +1,30 @@
+getNodeType());
+ }
+
+ public function test_emits_a_marker_for_every_file(): void
+ {
+ $collector = new AnalysisMarkerCollector;
+
+ // Scope is never touched by this collector, so a real FileNode over an
+ // empty statement list is enough to prove it always emits (non-null),
+ // which is what keeps CollectedDataNode rules reachable.
+ $result = $collector->processNode(new FileNode([]), $this->createStub(\PHPStan\Analyser\Scope::class));
+
+ self::assertNotNull($result);
+ self::assertTrue($result);
+ }
+}
diff --git a/tests/Helper/RelationFieldRegistryTest.php b/tests/Helper/RelationFieldRegistryTest.php
new file mode 100644
index 0000000..f9de46a
--- /dev/null
+++ b/tests/Helper/RelationFieldRegistryTest.php
@@ -0,0 +1,42 @@
+registry()->isRelation('relatedEntries'));
+ self::assertTrue($this->registry()->isRelation('heroImage'));
+ }
+
+ public function test_non_relational_fields_are_not_detected(): void
+ {
+ self::assertFalse($this->registry()->isRelation('summary'));
+ self::assertFalse($this->registry()->isRelation('title')); // native, non-relational
+ }
+
+ public function test_built_in_relation_accessors_are_detected(): void
+ {
+ self::assertTrue($this->registry()->isRelation('author'));
+ self::assertTrue($this->registry()->isRelation('children'));
+ self::assertTrue($this->registry()->isRelation('parent'));
+ }
+
+ public function test_falls_back_to_built_ins_when_config_missing(): void
+ {
+ $registry = new RelationFieldRegistry('/does/not/exist');
+ self::assertTrue($registry->isRelation('author'));
+ self::assertFalse($registry->isRelation('relatedEntries'));
+ }
+}
diff --git a/tests/Rule/TwigPerformanceRuleTest.php b/tests/Rule/TwigPerformanceRuleTest.php
new file mode 100644
index 0000000..e7352c2
--- /dev/null
+++ b/tests/Rule/TwigPerformanceRuleTest.php
@@ -0,0 +1,47 @@
+ true,
+ 'nestedRelationAll' => true,
+ 'queryInLoop' => true,
+ 'lengthOnQuery' => true,
+ 'unboundedAll' => false,
+ ]);
+
+ $scanner = new TwigTemplateScanner(
+ new TwigTemplateParser,
+ [__DIR__.'/../fixtures/templates'],
+ [],
+ );
+
+ return new TwigPerformanceRule($scanner, $analyzer, $enabled);
+ }
+
+ public function test_reports_n_plus_one_in_template_tree(): void
+ {
+ $errors = $this->rule()->scanTemplates();
+ $identifiers = array_map(static fn ($e) => $e->getIdentifier(), $errors);
+ self::assertContains('craftcms.twigNPlusOne', $identifiers);
+ }
+
+ public function test_no_errors_when_disabled(): void
+ {
+ self::assertSame([], $this->rule(enabled: false)->scanTemplates());
+ }
+}
diff --git a/tests/Twig/TwigPerformanceAnalyzerChecksTest.php b/tests/Twig/TwigPerformanceAnalyzerChecksTest.php
new file mode 100644
index 0000000..19312ac
--- /dev/null
+++ b/tests/Twig/TwigPerformanceAnalyzerChecksTest.php
@@ -0,0 +1,216 @@
+ true,
+ 'nestedRelationAll' => true,
+ 'queryInLoop' => true,
+ 'lengthOnQuery' => true,
+ 'unboundedAll' => true,
+ ];
+
+ /**
+ * @param array $checks
+ * @return list
+ */
+ private function ids(string $code, array $checks = self::ALL_CHECKS): array
+ {
+ $module = (new TwigTemplateParser)->parseSource($code);
+ self::assertNotNull($module);
+ $registry = new RelationFieldRegistry(__DIR__.'/../fixtures/projectConfig');
+ $findings = (new TwigPerformanceAnalyzer($registry, $checks))->analyze($module);
+
+ return array_map(static fn (Finding $f): string => $f->identifier, $findings);
+ }
+
+ public function test_nested_relation_all_in_loop(): void
+ {
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.all() %}
+ {% for cat in entry.relatedEntries.all() %}{{ cat.title }}{% endfor %}
+ {% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigNestedRelationAll', $this->ids($code));
+ }
+
+ public function test_nested_relation_all_suppressed_by_eagerly(): void
+ {
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.all() %}
+ {% for cat in entry.relatedEntries.eagerly().all() %}{{ cat.title }}{% endfor %}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNestedRelationAll', $this->ids($code));
+ }
+
+ public function test_query_built_in_loop(): void
+ {
+ $code = <<<'TWIG'
+ {% for id in ids %}
+ {% set e = craft.entries.id(id).one() %}{{ e.title }}
+ {% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigQueryInLoop', $this->ids($code));
+ }
+
+ public function test_length_on_query(): void
+ {
+ $code = '{{ craft.entries.section("news")|length }}';
+ self::assertContains('craftcms.twigLengthOnQuery', $this->ids($code));
+ }
+
+ public function test_length_on_plain_array_not_flagged(): void
+ {
+ $code = '{% set xs = [1, 2, 3] %}{{ xs|length }}';
+ self::assertNotContains('craftcms.twigLengthOnQuery', $this->ids($code));
+ }
+
+ public function test_unbounded_all_flagged_when_enabled(): void
+ {
+ $code = '{% set entries = craft.entries.section("news").all() %}';
+ self::assertContains('craftcms.twigUnboundedAll', $this->ids($code));
+ }
+
+ public function test_unbounded_all_silent_when_disabled(): void
+ {
+ $code = '{% set entries = craft.entries.section("news").all() %}';
+ self::assertNotContains('craftcms.twigUnboundedAll', $this->ids($code, ['unboundedAll' => false]));
+ }
+
+ public function test_unbounded_all_not_flagged_with_limit(): void
+ {
+ $code = '{% set entries = craft.entries.limit(10).all() %}';
+ self::assertNotContains('craftcms.twigUnboundedAll', $this->ids($code));
+ }
+
+ public function test_top_level_loop_source_query_not_flagged_as_query_in_loop(): void
+ {
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.section("news").all() %}{{ entry.title }}{% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigQueryInLoop', $this->ids($code, [
+ 'queryInLoop' => true,
+ 'unboundedAll' => false,
+ ]));
+ }
+
+ public function test_nested_loop_source_query_flagged_as_query_in_loop(): void
+ {
+ $code = <<<'TWIG'
+ {% for entry in entries %}
+ {% for asset in craft.assets.volume("x").all() %}{{ asset.title }}{% endfor %}
+ {% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigQueryInLoop', $this->ids($code, [
+ 'queryInLoop' => true,
+ 'unboundedAll' => false,
+ ]));
+ }
+
+ public function test_query_in_for_else_branch_not_flagged(): void
+ {
+ // The {% else %} branch runs at most once (when the sequence is empty),
+ // so a query there is not a per-iteration query.
+ $code = <<<'TWIG'
+ {% for entry in entries %}
+ {{ entry.title }}
+ {% else %}
+ {{ craft.entries.section("fallback").one().title }}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigQueryInLoop', $this->ids($code));
+ }
+
+ public function test_query_in_loop_fires_on_property_off_fetch(): void
+ {
+ $code = <<<'TWIG'
+ {% for x in xs %}{{ craft.entries.section("n").one().title }}{% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigQueryInLoop', $this->ids($code));
+ }
+
+ public function test_query_in_loop_fires_exactly_once_on_property_off_fetch(): void
+ {
+ $code = <<<'TWIG'
+ {% for x in xs %}{{ craft.entries.section("n").one().title }}{% endfor %}
+ TWIG;
+
+ $ids = $this->ids($code);
+ $count = count(array_filter($ids, static fn (string $id): bool => $id === 'craftcms.twigQueryInLoop'));
+
+ self::assertSame(1, $count);
+ }
+
+ public function test_query_in_loop_not_fired_on_relation_chain(): void
+ {
+ $code = <<<'TWIG'
+ {% for entry in entries %}{{ entry.relatedEntries.all() }}{% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigQueryInLoop', $this->ids($code));
+ }
+
+ public function test_relation_named_key_on_hash_literal_loop_not_flagged(): void
+ {
+ // The loop iterates a static hash literal, so `item` is a plain hash and
+ // `item.heroImage` reads a map key, not a Craft relation — no N+1.
+ $code = <<<'TWIG'
+ {% set items = { a: { heroImage: 'a.jpg' }, b: { heroImage: 'b.jpg' } } %}
+ {% for item in items %}{{ item.heroImage }}{% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->ids($code));
+ }
+
+ public function test_plainness_propagates_through_nested_literal_loops(): void
+ {
+ // Mirrors templates/_parts/font-preloading.twig: a hash of arrays of
+ // hashes. The inner value must still be recognised as plain.
+ $code = <<<'TWIG'
+ {% set groups = { g1: [ { heroImage: 'a.jpg' } ], g2: [ { heroImage: 'b.jpg' } ] } %}
+ {% for name, group in groups %}
+ {% for item in group %}{{ item.heroImage }}{% endfor %}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->ids($code));
+ }
+
+ public function test_relation_on_element_query_loop_still_flagged(): void
+ {
+ // Guard against over-suppression: a genuine element loop is unaffected.
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.all() %}{{ entry.heroImage }}{% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigNPlusOne', $this->ids($code));
+ }
+
+ public function test_nested_relation_all_on_hash_literal_loop_not_flagged(): void
+ {
+ $code = <<<'TWIG'
+ {% set items = [ { relatedEntries: 'x' } ] %}
+ {% for item in items %}{{ item.relatedEntries.all() }}{% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNestedRelationAll', $this->ids($code));
+ }
+}
diff --git a/tests/Twig/TwigPerformanceAnalyzerTest.php b/tests/Twig/TwigPerformanceAnalyzerTest.php
new file mode 100644
index 0000000..1d6f707
--- /dev/null
+++ b/tests/Twig/TwigPerformanceAnalyzerTest.php
@@ -0,0 +1,261 @@
+ $checks
+ * @return list
+ */
+ private function analyze(string $code, array $checks = ['nPlusOne' => true]): array
+ {
+ $module = (new TwigTemplateParser)->parseSource($code);
+ self::assertNotNull($module);
+
+ $registry = new RelationFieldRegistry(__DIR__.'/../fixtures/projectConfig');
+
+ return (new TwigPerformanceAnalyzer($registry, $checks))->analyze($module);
+ }
+
+ /**
+ * @param list $findings
+ */
+ private function identifiers(array $findings): array
+ {
+ return array_map(static fn (Finding $f): string => $f->identifier, $findings);
+ }
+
+ public function test_flags_relational_access_in_loop(): void
+ {
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.section('news').all() %}
+ {{ entry.author.fullName }}
+ {% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_does_not_flag_when_eager_loaded_with_with(): void
+ {
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.section('news').with(['author']).all() %}
+ {{ entry.author.fullName }}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_does_not_flag_when_access_uses_eagerly(): void
+ {
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.all() %}
+ {{ entry.author.eagerly().one().fullName }}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_does_not_flag_when_with_args_are_dynamic(): void
+ {
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.with(eagerFields).all() %}
+ {{ entry.author.fullName }}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_does_not_flag_non_relational_access(): void
+ {
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.all() %}
+ {{ entry.summary }}{{ entry.title }}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_resolves_loop_source_from_set_one_level_back(): void
+ {
+ $code = <<<'TWIG'
+ {% set entries = craft.entries.all() %}
+ {% for entry in entries %}
+ {{ entry.author.fullName }}
+ {% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_does_not_flag_relation_off_external_variable_chain(): void
+ {
+ // A partial (e.g. navigation/node.twig) receives an element that was
+ // eager-loaded in a parent template and passed across an {% include %}.
+ // `node` is undefined in this template, so its eager-load state is
+ // unknowable here and must not be assumed absent.
+ $code = <<<'TWIG'
+ {% for child in node.children %}
+ {{ child.children | length }}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_does_not_flag_relation_off_external_bare_variable(): void
+ {
+ // `entries` is supplied from outside this template (include var/global);
+ // we cannot see whether the upstream query eager-loaded `author`.
+ $code = <<<'TWIG'
+ {% for entry in entries %}
+ {{ entry.author.fullName }}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_does_not_flag_eager_loaded_relation_when_source_has_fallback(): void
+ {
+ // The `... .all() ?? []` idiom must not hide the query: `children` IS
+ // eager-loaded here (footer/careers navigation pattern), so accessing it
+ // on the loop items is not an N+1.
+ $code = <<<'TWIG'
+ {% set nodes = craft.navigation.nodes().handle('main').with(['children']).all() ?? [] %}
+ {% for node in nodes %}
+ {{ node.children | length }}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_still_flags_deeper_relation_not_eager_loaded_behind_fallback(): void
+ {
+ // Only `children` (level 2) is eager-loaded; `child.children` (level 3)
+ // is a genuine N+1 and must still fire even through the `?? []` fallback.
+ $code = <<<'TWIG'
+ {% set nodes = craft.navigation.nodes().handle('main').with(['children']).all() ?? [] %}
+ {% for node in nodes %}
+ {% for child in node.children %}
+ {{ child.children | length }}
+ {% endfor %}
+ {% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_still_flags_nested_relation_when_source_is_visible_query(): void
+ {
+ // The outer collection comes from a query we can see, so a nested
+ // relation that is not eager-loaded is a genuine N+1 and must still fire.
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.all() %}
+ {% for related in entry.relatedEntries %}
+ {{ related.author.fullName }}
+ {% endfor %}
+ {% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_flags_relation_on_outer_loop_variable_inside_nested_loop(): void
+ {
+ // `entry.author` runs once per `entry` iteration even though the access
+ // sits in an inner loop over a different variable — still an N+1.
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.all() %}
+ {% for size in [1, 2, 3] %}
+ {{ entry.author.fullName }}
+ {% endfor %}
+ {% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_inner_literal_loop_shadowing_the_variable_masks_the_outer_loop(): void
+ {
+ // The inner loop rebinds `entry` to plain hash values, so `entry.author`
+ // here reads a map key of the shadowing binding — not the outer element.
+ $code = <<<'TWIG'
+ {% for entry in craft.entries.all() %}
+ {% for entry in [{ author: 'jane' }] %}
+ {{ entry.author }}
+ {% endfor %}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_does_not_flag_first_segment_of_nested_eager_path(): void
+ {
+ // `with(['children.children'])` eager-loads the top-level `children`
+ // relation (and its `children`), so accessing `node.children` on the
+ // loop items is served from the eager-load cache — not an N+1.
+ $code = <<<'TWIG'
+ {% set nodes = craft.entries.with(['children.children']).all() %}
+ {% for node in nodes %}
+ {{ node.children | length }}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_does_not_flag_nested_relations_covered_by_deep_eager_path(): void
+ {
+ // The navigation menu pattern: a single deep eager-load path covers
+ // every level, so `children` accessed at each nesting depth is served
+ // from the eager-load cache. None of these are N+1s.
+ $code = <<<'TWIG'
+ {% set nodes = craft.navigation.nodes('main').with(['children.children.children']).all() %}
+ {% for node in nodes %}
+ {% set childNodes = node.children ?? [] %}
+ {% for subNode in childNodes %}
+ {% set childNodes = subNode.children ?? [] %}
+ {% for innerNode in childNodes %}
+ {{ innerNode.children | length }}
+ {% endfor %}
+ {% endfor %}
+ {% endfor %}
+ TWIG;
+
+ self::assertNotContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+
+ public function test_still_flags_relation_beyond_nested_eager_path_depth(): void
+ {
+ // `with(['children.children'])` covers two levels; the third-level
+ // `subNode.children` access is a genuine N+1 and must still fire.
+ $code = <<<'TWIG'
+ {% set nodes = craft.entries.with(['children.children']).all() %}
+ {% for node in nodes %}
+ {% for child in node.children %}
+ {% for subNode in child.children %}
+ {{ subNode.children | length }}
+ {% endfor %}
+ {% endfor %}
+ {% endfor %}
+ TWIG;
+
+ self::assertContains('craftcms.twigNPlusOne', $this->identifiers($this->analyze($code)));
+ }
+}
diff --git a/tests/Twig/TwigTemplateCacheMetaExtensionTest.php b/tests/Twig/TwigTemplateCacheMetaExtensionTest.php
new file mode 100644
index 0000000..5cc2831
--- /dev/null
+++ b/tests/Twig/TwigTemplateCacheMetaExtensionTest.php
@@ -0,0 +1,83 @@
+dir = sys_get_temp_dir().'/'.uniqid('twig_meta_', true);
+ mkdir($this->dir);
+ }
+
+ protected function tearDown(): void
+ {
+ foreach (glob($this->dir.'/*') ?: [] as $file) {
+ unlink($file);
+ }
+ @rmdir($this->dir);
+ }
+
+ private function extension(): TwigTemplateCacheMetaExtension
+ {
+ $scanner = new TwigTemplateScanner(new TwigTemplateParser, [$this->dir], []);
+
+ return new TwigTemplateCacheMetaExtension($scanner);
+ }
+
+ public function test_key_is_stable(): void
+ {
+ self::assertSame('craftTwigTemplates', $this->extension()->getKey());
+ }
+
+ public function test_hash_is_deterministic_for_unchanged_tree(): void
+ {
+ file_put_contents($this->dir.'/a.twig', '{{ foo }}');
+
+ self::assertSame($this->extension()->getHash(), $this->extension()->getHash());
+ }
+
+ public function test_hash_changes_when_template_content_changes(): void
+ {
+ $path = $this->dir.'/a.twig';
+ file_put_contents($path, '{{ foo }}');
+ $before = $this->extension()->getHash();
+
+ file_put_contents($path, '{{ bar }}');
+ $after = $this->extension()->getHash();
+
+ self::assertNotSame($before, $after);
+ }
+
+ public function test_hash_changes_when_template_is_added(): void
+ {
+ file_put_contents($this->dir.'/a.twig', '{{ foo }}');
+ $before = $this->extension()->getHash();
+
+ file_put_contents($this->dir.'/b.twig', '{{ foo }}');
+ $after = $this->extension()->getHash();
+
+ self::assertNotSame($before, $after);
+ }
+
+ public function test_hash_changes_when_template_is_removed(): void
+ {
+ file_put_contents($this->dir.'/a.twig', '{{ foo }}');
+ file_put_contents($this->dir.'/b.twig', '{{ foo }}');
+ $before = $this->extension()->getHash();
+
+ unlink($this->dir.'/b.twig');
+ $after = $this->extension()->getHash();
+
+ self::assertNotSame($before, $after);
+ }
+}
diff --git a/tests/Twig/TwigTemplateParserTest.php b/tests/Twig/TwigTemplateParserTest.php
new file mode 100644
index 0000000..8e548c6
--- /dev/null
+++ b/tests/Twig/TwigTemplateParserTest.php
@@ -0,0 +1,74 @@
+parser = new TwigTemplateParser;
+ }
+
+ public function test_parses_plain_template(): void
+ {
+ $module = $this->parser->parseSource('{{ entry.title }}');
+ self::assertInstanceOf(ModuleNode::class, $module);
+ }
+
+ public function test_parses_craft_custom_tags_without_error(): void
+ {
+ $code = <<<'TWIG'
+ {% cache %}
+ {% nav node in nodes %}
+ {{ node.title }}
+ {% endnav %}
+ {% switch entry.type %}
+ {% case "news" %}news{% endcase %}
+ {% endswitch %}
+ {% exit 404 %}
+ {% endcache %}
+ TWIG;
+
+ self::assertInstanceOf(ModuleNode::class, $this->parser->parseSource($code));
+ }
+
+ public function test_parses_unknown_functions_and_filters(): void
+ {
+ $code = '{{ getCsrfInput() }}{{ entry.body|markdown|t }}';
+ self::assertInstanceOf(ModuleNode::class, $this->parser->parseSource($code));
+ }
+
+ public function test_returns_null_on_broken_template(): void
+ {
+ // Unterminated block — unrecoverable even for a permissive parser.
+ self::assertNull($this->parser->parseSource('{% for x in y %}'));
+ }
+
+ public function test_parses_file_from_disk(): void
+ {
+ // Create a temporary file with Twig content.
+ $tempPath = sys_get_temp_dir().'/'.uniqid('twig_test_', true).'.twig';
+ file_put_contents($tempPath, '{{ entry.title }}');
+
+ try {
+ $module = $this->parser->parseFile($tempPath);
+ self::assertInstanceOf(ModuleNode::class, $module);
+ } finally {
+ unlink($tempPath);
+ }
+ }
+
+ public function test_returns_null_for_missing_file(): void
+ {
+ $module = $this->parser->parseFile('/does/not/exist/nope.twig');
+ self::assertNull($module);
+ }
+}
diff --git a/tests/Twig/TwigTemplateScannerTest.php b/tests/Twig/TwigTemplateScannerTest.php
new file mode 100644
index 0000000..bb87740
--- /dev/null
+++ b/tests/Twig/TwigTemplateScannerTest.php
@@ -0,0 +1,89 @@
+scanner([self::FIXTURES])->templateFiles();
+
+ $basenames = array_map('basename', $files);
+ self::assertContains('clean.twig', $basenames);
+ self::assertContains('nplusone.twig', $basenames);
+ }
+
+ public function test_prunes_excluded_directories(): void
+ {
+ $basenames = array_map('basename', $this->scanner([self::FIXTURES], [], ['vendor'])->templateFiles());
+
+ self::assertNotContains('bundled.twig', $basenames);
+ self::assertContains('clean.twig', $basenames);
+ }
+
+ public function test_excluded_directories_are_scanned_when_not_configured(): void
+ {
+ $basenames = array_map('basename', $this->scanner([self::FIXTURES])->templateFiles());
+
+ self::assertContains('bundled.twig', $basenames);
+ }
+
+ public function test_returns_stable_sorted_order(): void
+ {
+ $files = $this->scanner([self::FIXTURES])->templateFiles();
+
+ $sorted = $files;
+ sort($sorted);
+ self::assertSame($sorted, $files);
+ }
+
+ public function test_merges_and_deduplicates_both_path_lists(): void
+ {
+ // Same directory in both lists must not yield duplicate entries.
+ $files = $this->scanner([self::FIXTURES], [self::FIXTURES])->templateFiles();
+
+ self::assertSame(array_values(array_unique($files)), $files);
+ }
+
+ public function test_covers_directories_from_both_configs(): void
+ {
+ // A directory configured only for performance must still be scanned.
+ $files = $this->scanner([], [self::FIXTURES])->templateFiles();
+
+ self::assertNotSame([], $files);
+ }
+
+ public function test_ignores_missing_directories(): void
+ {
+ $files = $this->scanner(['/does/not/exist'])->templateFiles();
+
+ self::assertSame([], $files);
+ }
+
+ public function test_scan_yields_lazily_readable_templates(): void
+ {
+ $templates = iterator_to_array($this->scanner([self::FIXTURES])->scan());
+
+ self::assertNotEmpty($templates);
+ self::assertContainsOnlyInstancesOf(ScannedTemplate::class, $templates);
+
+ $first = $templates[0];
+ self::assertIsString($first->contents());
+ self::assertInstanceOf(ModuleNode::class, $first->module());
+ }
+}
diff --git a/tests/fixtures/projectConfig/fields/heroImage.yaml b/tests/fixtures/projectConfig/fields/heroImage.yaml
new file mode 100644
index 0000000..0ba1bc7
--- /dev/null
+++ b/tests/fixtures/projectConfig/fields/heroImage.yaml
@@ -0,0 +1,2 @@
+handle: heroImage
+type: craft\fields\Assets
diff --git a/tests/fixtures/projectConfig/fields/relatedEntries.yaml b/tests/fixtures/projectConfig/fields/relatedEntries.yaml
new file mode 100644
index 0000000..c2cf241
--- /dev/null
+++ b/tests/fixtures/projectConfig/fields/relatedEntries.yaml
@@ -0,0 +1,2 @@
+handle: relatedEntries
+type: craft\fields\Entries
diff --git a/tests/fixtures/projectConfig/fields/summary.yaml b/tests/fixtures/projectConfig/fields/summary.yaml
new file mode 100644
index 0000000..48f8356
--- /dev/null
+++ b/tests/fixtures/projectConfig/fields/summary.yaml
@@ -0,0 +1,2 @@
+handle: summary
+type: craft\fields\PlainText
diff --git a/tests/fixtures/templates/clean.twig b/tests/fixtures/templates/clean.twig
new file mode 100644
index 0000000..507091e
--- /dev/null
+++ b/tests/fixtures/templates/clean.twig
@@ -0,0 +1,3 @@
+{% for entry in craft.entries.section('news').with(['author']).all() %}
+ {{ entry.author.fullName }}
+{% endfor %}
diff --git a/tests/fixtures/templates/nplusone.twig b/tests/fixtures/templates/nplusone.twig
new file mode 100644
index 0000000..6dc5a72
--- /dev/null
+++ b/tests/fixtures/templates/nplusone.twig
@@ -0,0 +1,3 @@
+{% for entry in craft.entries.section('news').all() %}
+ {{ entry.author.fullName }}
+{% endfor %}
diff --git a/tests/fixtures/templates/vendor/bundled.twig b/tests/fixtures/templates/vendor/bundled.twig
new file mode 100644
index 0000000..2618abd
--- /dev/null
+++ b/tests/fixtures/templates/vendor/bundled.twig
@@ -0,0 +1,2 @@
+{# A third-party template that lives under vendor/ and must be excludable. #}
+{% for entry in craft.entries.all() %}{{ entry.author.name }}{% endfor %}