From 164f1076a49e90bbcfdf0fd458a9f346e627bc44 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 01:29:57 -0300 Subject: [PATCH 01/19] chore: upgrade packages --- .github/workflows/php.yml | 19 +- CLAUDE.md | 38 ++++ composer.json | 8 +- example/index.php | 139 ++++++------- phpunit.xml | 23 ++- tests/TreeWalkerTest.php | 409 +++++++++++++++++++++++++++++++------- 6 files changed, 469 insertions(+), 167 deletions(-) create mode 100644 CLAUDE.md diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index f115418..c2ee90d 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -5,26 +5,31 @@ on: [push] jobs: build: runs-on: ubuntu-latest + strategy: + matrix: + php-version: ["8.1", "8.2", "8.3"] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - - name: Xdebug Action - uses: MilesChou/docker-xdebug@v1.0.0 + - name: Setup PHP with Xdebug + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: xdebug - name: Validate composer.json and composer.lock run: composer validate - name: Install dependencies - run: composer install --prefer-dist --no-progress --no-suggest + run: composer install --prefer-dist --no-progress - name: Run test suite run: composer run-script test - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 + if: matrix.php-version == '8.3' + uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} file: ./coverage.xml - # - name: Run codecov - # run: bash <(curl -s https://codecov.io/bash) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..3f7d62b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,38 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Commands + +```sh +composer install # install dev deps (phpunit 5, phpcs) +composer test # run phpunit with coverage-text +composer check-format # phpcs PSR2 lint over src/ +composer format # phpcbf PSR2 autofix over src/ and tests/ + +vendor/bin/phpunit tests/TreeWalkerTest.php # run a single test file +vendor/bin/phpunit --filter testSimpleStructs # run a single test method +``` + +CI (`.github/workflows/php.yml`) runs `composer test` on push and uploads `coverage.xml` to Codecov. PHP >= 5.5 is the supported floor. + +## Architecture + +Single-class library: `src/TreeWalker.php` (no namespace; PSR-4 autoload maps `""` → `src/`). Tests live in `tests/`; an interactive demo is in `example/index.php`. + +The public API operates on three interchangeable structure shapes — JSON string, `\stdClass` object, or associative array — configured per-instance via the constructor's `returntype` option (`"jsonstring" | "object" | "array"`) plus a `debug` flag that appends a `time` key to outputs. + +Two pieces of internal machinery are load-bearing and worth understanding before editing any public method: + +1. **`studyType(&$struct, &$problem)`** is called at the top of every public method. It normalizes the input in place to an associative array (decoding JSON strings, casting objects), or returns `false` with an error message. Public methods always work in array-space internally. + +2. **`returnTypeConvert($struct)`** is the matching exit converter, encoding the result back to whatever `returntype` was configured. New public methods must funnel through this — never return raw arrays. + +The diff/merge implementation uses a **path-flattening** strategy rather than recursive structural comparison: + +- `structPathArray()` walks a nested structure and produces a flat associative array keyed by slash-delimited paths (e.g. `"cafeina/ss/ff" => 21`). +- `getdiff()` and `structMerge()` both flatten both inputs, then operate on the flat maps (`structPathArrayDiff`, `array_merge`). +- `pathSlashToStruct()` is the inverse — it re-nests slash-keys back into a tree, and is gated by the `$slashtoobject` parameter on `getdiff` / `structMerge`. Note the README examples pass `true` to mean "no slashes / nested output" — the boolean naming is counter-intuitive. +- `pathSlashToStruct()` calls `createDynamicallyObjects()` + `setDynamicallyValue()` internally; those helpers depend on `returntype` being `"array"`, so it temporarily flips the config via `switchType()` and flips it back at the end. Anything that calls these helpers from a non-array return-type context must do the same dance. + +`walker()` is the only method that does true recursive in-place mutation (callback receives `&$struct, $key, &$value`); it does not go through the path-flattening pipeline. diff --git a/composer.json b/composer.json index 6c34bc1..451b199 100644 --- a/composer.json +++ b/composer.json @@ -19,10 +19,12 @@ "email": "lukas_civil@hotmail.com" } ], - "require": {}, + "require": { + "php": ">=8.1" + }, "autoload": { "psr-4": { - "": "src/" + "Lukascivil\\TreeWalker\\": "src/" } }, "scripts": { @@ -31,7 +33,7 @@ "format": "vendor/bin/phpcbf --standard=PSR2 src && vendor/bin/phpcbf --standard=PSR2 tests" }, "require-dev": { - "phpunit/phpunit": "^5", + "phpunit/phpunit": "^10", "squizlabs/php_codesniffer": "3.*" } } diff --git a/example/index.php b/example/index.php index b293aae..e1bcfb8 100644 --- a/example/index.php +++ b/example/index.php @@ -1,88 +1,75 @@ true, //true => return the time, false => not - "returntype" => "jsonstring" //Returntype = ["object","jsonstring","array"] - )); +require_once __DIR__ . '/../vendor/autoload.php'; - $struct1 = utf8_encode(file_get_contents('json/json1.json')); - $struct2 = json_decode(utf8_encode(file_get_contents('json/json2.json')), true); - $struct3 = array("casa"=>1, "b"=>"5", "cafeina"=>array("ss1"=>"1", "ss2"=>"2"), "oi"=>5, "1" => "255"); - $struct4 = array("casa"=>2, "cafeina"=>array("ss"=>array("ff"=>21, "ff1"=>22)), "oi2"=>5, "1"=>"", "ss"=>"dddddf"); +use Lukascivil\TreeWalker\TreeWalker; - $struct5 = new stdClass(); - $struct5->oi = "s55"; - $struct5->cafe = "quente"; - $struct5->oi1 = "oi1"; +$treewalker = new TreeWalker([ + 'debug' => true, + 'returntype' => 'jsonstring', +]); - class classstruct1 { - public $cafe = "frio"; - } - - class classstruct2 extends classstruct1 { - public $struct4cc = "2"; - } - - $struct6 = new classstruct1(); - $struct7 = new classstruct2(); - - $struct8 = $struct3; - $struct8["cafeina"]["ss"] = new classstruct2(); - - //getdiff(modified struct, static struct, slashtostruct) ------------------------------- - //slashtostruct can be true or false - echo "\ngetdiff(modified struct, static struct, slashtostruct)
\n"; - print_r($treewalker->getdiff($struct1, $struct2, true)); - echo "

\n\n"; +$struct1 = file_get_contents(__DIR__ . '/json/json1.json'); +$struct2 = json_decode(file_get_contents(__DIR__ . '/json/json2.json'), true); +$struct3 = ['casa' => 1, 'b' => '5', 'cafeina' => ['ss1' => '1', 'ss2' => '2'], 'oi' => 5, '1' => '255']; +$struct4 = ['casa' => 2, 'cafeina' => ['ss' => ['ff' => 21, 'ff1' => 22]], 'oi2' => 5, '1' => '', 'ss' => 'dddddf']; - //walker(struct, function) ------------------------------------------------------------- - echo "walker(struct, function)
\n"; - print_r($treewalker->walker($struct4, function(&$struct, $key, &$value) { - //Removing element - if ($key == "ff") { - unset($struct[$key]); - } +$struct5 = new stdClass(); +$struct5->oi = 's55'; +$struct5->cafe = 'quente'; +$struct5->oi1 = 'oi1'; - //changing element - if ($key == "ff1") { - $value = array("son" => "tiago"); - } - })); - echo "

\n\n"; +class classstruct1 +{ + public $cafe = 'frio'; +} - //createDynamicallyObjects(struct, newObjectPath) --------------------------------------- - echo "createDynamicallyObjects(struct, newObjectPath)
\n"; - print_r($treewalker->createDynamicallyObjects($struct3, array("cafeina", "novo"))); - echo "

\n\n"; +class classstruct2 extends classstruct1 +{ + public $struct4cc = '2'; +} - //getDynamicallyValue(struct, static) --------------------------------------------------- - echo "getDynamicallyValue(struct, static)
\n"; +$struct6 = new classstruct1(); +$struct7 = new classstruct2(); - echo "Static access
\n"; - print_r($struct4["cafeina"]["ss"]); // Static access +$struct8 = $struct3; +$struct8['cafeina']['ss'] = new classstruct2(); - echo "\n
Dynamic access
\n"; - $dynamicpath = array("cafeina","ss"); - print_r($treewalker->getDynamicallyValue($struct4, $dynamicpath)); // Dynamic access - echo "
\n\n"; +// getdiff(modified struct, static struct, slashtostruct) +echo "\ngetdiff(modified struct, static struct, slashtostruct)
\n"; +print_r($treewalker->getdiff($struct1, $struct2, true)); +echo "

\n\n"; - //setDynamicallyValue(struct, static, value) -------------------------------------------- - echo "setDynamicallyValue(struct, static, value)
\n"; - - echo "Static access
\n"; - $struct4["cafeina"]["ss"] = "newvalue";// Static access - print_r($struct4); - - $struct4["cafeina"]["ss"] = ""; - - echo "\n
Dynamic access
\n"; - $dynamicpath = array("cafeina","ss"); - print_r($treewalker->setDynamicallyValue($struct4, $dynamicpath, "newvalue")); // Dynamic access - echo "
\n\n"; - - //structMerge(struct, static, slashtostruct) -------------------------------------------- - echo "\n
structMerge
\n"; - print_r($treewalker->structMerge($struct4, $struct3, true)); - echo "
\n\n"; -?> +// walker(struct, function) +echo "walker(struct, function)
\n"; +print_r($treewalker->walker($struct4, function (array &$struct, $key, &$value): void { + if ($key === 'ff') { + unset($struct[$key]); + } + if ($key === 'ff1') { + $value = ['son' => 'tiago']; + } +})); +echo "

\n\n"; + +// createDynamicallyObjects(struct, newObjectPath) +echo "createDynamicallyObjects(struct, newObjectPath)
\n"; +print_r($treewalker->createDynamicallyObjects($struct3, ['cafeina', 'novo'])); +echo "

\n\n"; + +// getDynamicallyValue(struct, path) +echo "getDynamicallyValue(struct, path)
\n"; +$dynamicpath = ['cafeina', 'ss']; +print_r($treewalker->getDynamicallyValue($struct4, $dynamicpath)); +echo "
\n\n"; + +// setDynamicallyValue(struct, path, value) +echo "setDynamicallyValue(struct, path, value)
\n"; +$dynamicpath = ['cafeina', 'ss']; +print_r($treewalker->setDynamicallyValue($struct4, $dynamicpath, 'newvalue')); +echo "
\n\n"; + +// structMerge(struct1, struct2, slashtostruct) +echo "structMerge
\n"; +print_r($treewalker->structMerge($struct4, $struct3, true)); +echo "
\n\n"; diff --git a/phpunit.xml b/phpunit.xml index 392c729..997c60f 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,16 +1,19 @@ - - - - + tests/ - - - ./src - - - \ No newline at end of file + + + ./src + + + + + + diff --git a/tests/TreeWalkerTest.php b/tests/TreeWalkerTest.php index f4ad86d..0f1a82a 100644 --- a/tests/TreeWalkerTest.php +++ b/tests/TreeWalkerTest.php @@ -1,77 +1,344 @@ false, - "returntype" => "array" - )); - $struct1 = array( - '1' => array('2' => '7', '3' => array('4' => '6')) - ); - $struct2 = array( - '1' => array('3' => array('4' => '5')) - ); - $expectedResult = array( - 'edited'=> array('1/3/4'=> array('newvalue'=> '5', 'oldvalue'=> '6' )), - 'new'=> array(), - 'removed'=> array( '1/2'=> '7' ) - ); - $result = $treewalker->getdiff($struct2, $struct1, false); - - $this->assertEquals($result, $expectedResult); - } - - public function testStructsContainingArrayProperty() - { - $treewalker = new TreeWalker(array( - "debug" => false, - "returntype" => "array" - )); - $struct1 = array( - 'a' => 1, - 'b' => array(array('c1' => 1), array('c2' => 2)) - ); - $struct2 = array( - 'a' => 11, - 'b' => array(array('c1' => 1), array('c2' => 22)) - ); - $expectedResult = array( - 'edited'=> array('a'=> array('newvalue'=> 11, 'oldvalue'=> 1 ), 'b/1/c2'=> array('newvalue'=> 22, 'oldvalue'=> 2 )), - 'new'=> array(), - 'removed'=> array() - ); - $result = $treewalker->getdiff($struct2, $struct1, false); - - $this->assertEquals($result, $expectedResult); - } - - public function testStructsContainingDifferentTypes() - { - $treewalker = new TreeWalker(array( - "debug" => false, - "returntype" => "array" - )); - $struct1 = array( - 'a' => 1, - 'b' => array('c1' => 2), - 'c' => 3 - ); - $struct2 = array( - 'a' => '1', - 'b' => 2, - 'c' => true - ); - $expectedResult = array( - 'edited'=> array('a'=> array('newvalue'=> '1', 'oldvalue'=> 1 ), 'c'=> array('newvalue'=> true, 'oldvalue'=> 3 )), - 'new'=> array('b' => 2), - 'removed'=> array('b/c1' => 2) - ); - $result = $treewalker->getdiff($struct2, $struct1, false); - - $this->assertEquals($result, $expectedResult); + // ------------------------------------------------------------------------- + // getdiff + // ------------------------------------------------------------------------- + + public function testGetdiffSimpleStructs(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct1 = ['1' => ['2' => '7', '3' => ['4' => '6']]]; + $struct2 = ['1' => ['3' => ['4' => '5']]]; + + $expected = [ + 'edited' => ['1/3/4' => ['newvalue' => '5', 'oldvalue' => '6']], + 'new' => [], + 'removed' => ['1/2' => '7'], + ]; + + $this->assertEquals($expected, $tw->getdiff($struct2, $struct1, false)); + } + + public function testGetdiffWithArrayProperty(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct1 = ['a' => 1, 'b' => [['c1' => 1], ['c2' => 2]]]; + $struct2 = ['a' => 11, 'b' => [['c1' => 1], ['c2' => 22]]]; + + $expected = [ + 'edited' => [ + 'a' => ['newvalue' => 11, 'oldvalue' => 1], + 'b/1/c2' => ['newvalue' => 22, 'oldvalue' => 2], + ], + 'new' => [], + 'removed' => [], + ]; + + $this->assertEquals($expected, $tw->getdiff($struct2, $struct1, false)); + } + + public function testGetdiffWithDifferentTypes(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct1 = ['a' => 1, 'b' => ['c1' => 2], 'c' => 3]; + $struct2 = ['a' => '1', 'b' => 2, 'c' => true]; + + $expected = [ + 'edited' => [ + 'a' => ['newvalue' => '1', 'oldvalue' => 1], + 'c' => ['newvalue' => true, 'oldvalue' => 3], + ], + 'new' => ['b' => 2], + 'removed' => ['b/c1' => 2], + ]; + + $this->assertEquals($expected, $tw->getdiff($struct2, $struct1, false)); + } + + public function testGetdiffSlashToObject(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct1 = ['a' => ['b' => 1]]; + $struct2 = ['a' => ['b' => 2]]; + + $result = $tw->getdiff($struct1, $struct2, true); + + $this->assertArrayHasKey('edited', $result); + $this->assertArrayHasKey('a', $result['edited']); + $this->assertArrayHasKey('b', $result['edited']['a']); + } + + public function testGetdiffWithJsonStringInput(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $json1 = '{"a": 1, "b": 2}'; + $json2 = '{"a": 1, "b": 3}'; + + $result = $tw->getdiff($json1, $json2, false); + + $this->assertArrayHasKey('edited', $result); + $this->assertArrayHasKey('b', $result['edited']); + $this->assertEquals(3, $result['edited']['b']['oldvalue']); + $this->assertEquals(2, $result['edited']['b']['newvalue']); + } + + public function testGetdiffWithObjectInput(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct1 = (object) ['a' => 1, 'b' => 2]; + $struct2 = (object) ['a' => 1, 'b' => 3]; + + $result = $tw->getdiff($struct1, $struct2, false); + + $this->assertArrayHasKey('edited', $result); + $this->assertArrayHasKey('b', $result['edited']); + } + + // ------------------------------------------------------------------------- + // getdiff return types + // ------------------------------------------------------------------------- + + public function testGetdiffReturnsJsonString(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'jsonstring']); + + $result = $tw->getdiff(['a' => 1], ['a' => 2], false); + + $this->assertIsString($result); + $this->assertIsArray(json_decode($result, true)); + } + + public function testGetdiffReturnsObject(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'object']); + + $result = $tw->getdiff(['a' => 1], ['a' => 2], false); + + $this->assertIsObject($result); + $this->assertObjectHasProperty('edited', $result); + } + + // ------------------------------------------------------------------------- + // getDynamicallyValue + // ------------------------------------------------------------------------- + + public function testGetDynamicallyValueReturnsScalar(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct = ['a' => ['b' => ['c' => 42]]]; + + $this->assertEquals(42, $tw->getDynamicallyValue($struct, ['a', 'b', 'c'])); + } + + public function testGetDynamicallyValueReturnsNestedArray(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct = ['a' => ['b' => ['x' => 1, 'y' => 2]]]; + + $this->assertEquals(['x' => 1, 'y' => 2], $tw->getDynamicallyValue($struct, ['a', 'b'])); + } + + public function testGetDynamicallyValueWithJsonInput(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $this->assertEquals(99, $tw->getDynamicallyValue('{"a": {"b": 99}}', ['a', 'b'])); + } + + public function testGetDynamicallyValueThrowsOnMissingKey(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $this->expectException(\RuntimeException::class); + $tw->getDynamicallyValue(['a' => ['b' => 1]], ['a', 'missing']); + } + + // ------------------------------------------------------------------------- + // setDynamicallyValue + // ------------------------------------------------------------------------- + + public function testSetDynamicallyValueUpdatesNestedKey(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct = ['a' => ['b' => 1]]; + $result = $tw->setDynamicallyValue($struct, ['a', 'b'], 99); + + $this->assertEquals(['a' => ['b' => 99]], $result); + } + + public function testSetDynamicallyValueDoesNotMutateOriginal(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct = ['a' => ['b' => 1]]; + $tw->setDynamicallyValue($struct, ['a', 'b'], 99); + + $this->assertEquals(1, $struct['a']['b']); + } + + public function testSetDynamicallyValueThrowsOnMissingKey(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $this->expectException(\RuntimeException::class); + $tw->setDynamicallyValue(['a' => ['b' => 1]], ['a', 'missing', 'deep'], 5); + } + + // ------------------------------------------------------------------------- + // createDynamicallyObjects + // ------------------------------------------------------------------------- + + public function testCreateDynamicallyObjectsOnEmptyStruct(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $result = $tw->createDynamicallyObjects([], ['level1', 'level2']); + + $this->assertEquals(['level1' => ['level2' => []]], $result); + } + + public function testCreateDynamicallyObjectsAddsToExistingStruct(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct = ['existing' => 1]; + $result = $tw->createDynamicallyObjects($struct, ['new', 'path']); + + $this->assertArrayHasKey('existing', $result); + $this->assertArrayHasKey('new', $result); + $this->assertEquals([], $result['new']['path']); + } + + // ------------------------------------------------------------------------- + // walker + // ------------------------------------------------------------------------- + + public function testWalkerMultipliesIntValues(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct = ['a' => 1, 'b' => 2, 'c' => ['d' => 3]]; + $result = $tw->walker($struct, function (array &$node, $key, &$value): void { + if (is_int($value)) { + $value = $value * 2; + } + }); + + $this->assertEquals(['a' => 2, 'b' => 4, 'c' => ['d' => 6]], $result); + } + + public function testWalkerDeletesNode(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct = ['a' => 1, 'b' => 2, 'c' => 3]; + $result = $tw->walker($struct, function (array &$node, $key, &$value): void { + if ($key === 'b') { + unset($node[$key]); + } + }); + + $this->assertEquals(['a' => 1, 'c' => 3], $result); + } + + public function testWalkerWithJsonInput(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct = '{"x": 10, "y": 20}'; + $result = $tw->walker($struct, function (array &$node, $key, &$value): void { + if (is_int($value)) { + $value = 0; + } + }); + + $this->assertEquals(['x' => 0, 'y' => 0], $result); + } + + // ------------------------------------------------------------------------- + // structMerge + // ------------------------------------------------------------------------- + + public function testStructMergeFirstOverridesSecond(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct1 = ['a' => 1, 'b' => 2]; + $struct2 = ['b' => 99, 'c' => 3]; + + $result = $tw->structMerge($struct1, $struct2, false); + + $this->assertEquals(1, $result['a']); + $this->assertEquals(2, $result['b']); // struct1 wins + $this->assertEquals(3, $result['c']); + } + + public function testStructMergeFlattensNestedStructs(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct1 = ['a' => ['b' => 1]]; + $struct2 = ['a' => ['c' => 2]]; + + $result = $tw->structMerge($struct1, $struct2, false); + + $this->assertArrayHasKey('a/b', $result); + $this->assertArrayHasKey('a/c', $result); + } + + public function testStructMergeSlashToObject(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + + $struct1 = ['a' => ['b' => 1]]; + $struct2 = ['a' => ['c' => 2]]; + + $result = $tw->structMerge($struct1, $struct2, true); + + $this->assertArrayHasKey('a', $result); + $this->assertArrayHasKey('b', $result['a']); + $this->assertArrayHasKey('c', $result['a']); + } + + // ------------------------------------------------------------------------- + // debug mode + // ------------------------------------------------------------------------- + + public function testDebugModeAddsTimeKey(): void + { + $tw = new TreeWalker(['debug' => true, 'returntype' => 'array']); + + $result = $tw->getdiff(['a' => 1], ['a' => 2], false); + + $this->assertArrayHasKey('time', $result); + $this->assertStringContainsString('milliseconds', $result['time']); + } + + // ------------------------------------------------------------------------- + // invalid input + // ------------------------------------------------------------------------- + + public function testInvalidReturnTypeThrows(): void + { + $tw = new TreeWalker(['debug' => false, 'returntype' => 'invalid']); + + $this->expectException(\InvalidArgumentException::class); + $tw->getdiff(['a' => 1], ['a' => 2], false); } } From a2f70b253830fb66b97b01dbfae89d5394ca7d64 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 02:27:20 -0300 Subject: [PATCH 02/19] Update composer.lock --- composer.lock | 1512 +++++++++++++++++++++++++++++-------------------- 1 file changed, 913 insertions(+), 599 deletions(-) diff --git a/composer.lock b/composer.lock index 22bf86f..56158d6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,98 +4,44 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c56596155203351f025bb6d7f668446d", + "content-hash": "1997e5fc03e3fc4a199c245852aac78f", "packages": [], "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", - "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2019-10-21T16:45:58+00:00" - }, { "name": "myclabs/deep-copy", - "version": "1.9.4", + "version": "1.13.4", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "579bb7356d91f9456ccd505f24ca8b667966a0a7" + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/579bb7356d91f9456ccd505f24ca8b667966a0a7", - "reference": "579bb7356d91f9456ccd505f24ca8b667966a0a7", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.1 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "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": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, "files": [ "src/DeepCopy/deep_copy.php" - ] + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -109,257 +55,234 @@ "object", "object graph" ], - "time": "2019-12-15T19:12:40+00:00" + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "2.0.0", + "name": "nikic/php-parser", + "version": "v5.7.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "phpunit/phpunit": "~6" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src/" + "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" + "name": "Nikita Popov" } ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", + "description": "A PHP parser written in PHP", "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" + "parser", + "php" ], - "time": "2018-08-07T13:53:10+00:00" + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + }, + "time": "2025-12-06T11:56:16+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.3", + "name": "phar-io/manifest", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62" + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62", - "reference": "2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", - "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "^1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-12-20T13:40:23+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "shasum": "" - }, - "require": { - "php": "^7.1", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "^7.1", - "mockery/mockery": "~1", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "url": "https://github.com/theseer", + "type": "github" } ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2019-08-22T18:11:29+00:00" + "time": "2024-03-03T12:33:53+00:00" }, { - "name": "phpspec/prophecy", - "version": "1.10.0", + "name": "phar-io/version", + "version": "3.2.1", "source": { "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "d638ebbb58daba25a6a0dc7969e1358a0e3c6682" + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d638ebbb58daba25a6a0dc7969e1358a0e3c6682", - "reference": "d638ebbb58daba25a6a0dc7969e1358a0e3c6682", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + "php": "^7.2 || ^8.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10.x-dev" - } - }, "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" }, { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2019-12-17T16:54:23+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": "phpunit/php-code-coverage", - "version": "4.0.8", + "version": "10.1.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", - "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-xmlwriter": "*", - "php": "^5.6 || ^7.0", - "phpunit/php-file-iterator": "^1.3", - "phpunit/php-text-template": "^1.2", - "phpunit/php-token-stream": "^1.4.2 || ^2.0", - "sebastian/code-unit-reverse-lookup": "^1.0", - "sebastian/environment": "^1.3.2 || ^2.0", - "sebastian/version": "^1.0 || ^2.0" + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "ext-xdebug": "^2.1.4", - "phpunit/phpunit": "^5.7" + "phpunit/phpunit": "^10.1" }, "suggest": { - "ext-xdebug": "^2.5.1" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-main": "10.1.x-dev" } }, "autoload": { @@ -374,7 +297,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -385,29 +308,43 @@ "testing", "xunit" ], - "time": "2017-04-02T07:44:40+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:31:57+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.5", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -422,7 +359,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -432,26 +369,49 @@ "filesystem", "iterator" ], - "time": "2017-11-27T13:52:08+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" }, { - "name": "phpunit/php-text-template", - "version": "1.2.1", + "name": "phpunit/php-invoker", + "version": "4.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -468,37 +428,47 @@ "role": "lead" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", "keywords": [ - "template" + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "time": "2015-06-21T13:50:34+00:00" + "time": "2023-02-03T06:56:09+00:00" }, { - "name": "phpunit/php-timer", - "version": "1.0.9", + "name": "phpunit/php-text-template", + "version": "3.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -513,42 +483,52 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "timer" + "template" ], - "time": "2017-02-26T11:10:40+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" }, { - "name": "phpunit/php-token-stream", - "version": "2.0.2", + "name": "phpunit/php-timer", + "version": "6.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": "^7.0" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^6.2.4" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -563,28 +543,39 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ - "tokenizer" + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "time": "2017-11-27T05:48:46+00:00" + "time": "2023-02-03T06:57:52+00:00" }, { "name": "phpunit/phpunit", - "version": "5.7.27", + "version": "10.5.63", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c" + "reference": "33198268dad71e926626b618f3ec3966661e4d90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", - "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33198268dad71e926626b618f3ec3966661e4d90", + "reference": "33198268dad71e926626b618f3ec3966661e4d90", "shasum": "" }, "require": { @@ -593,33 +584,30 @@ "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "~1.3", - "php": "^5.6 || ^7.0", - "phpspec/prophecy": "^1.6.2", - "phpunit/php-code-coverage": "^4.0.4", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "^3.2", - "sebastian/comparator": "^1.2.4", - "sebastian/diff": "^1.4.3", - "sebastian/environment": "^1.3.4 || ^2.0", - "sebastian/exporter": "~2.0", - "sebastian/global-state": "^1.1", - "sebastian/object-enumerator": "~2.0", - "sebastian/resource-operations": "~1.0", - "sebastian/version": "^1.0.6|^2.0.1", - "symfony/yaml": "~2.1|~3.0|~4.0" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2" - }, - "require-dev": { - "ext-pdo": "*" + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.5", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.4", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.1", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" }, "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "~1.1" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -627,10 +615,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.7.x-dev" + "dev-main": "10.5-dev" } }, "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], "classmap": [ "src/" ] @@ -653,41 +644,59 @@ "testing", "xunit" ], - "time": "2018-02-01T05:50:59+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.63" + }, + "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-01-27T05:48:37+00:00" }, { - "name": "phpunit/phpunit-mock-objects", - "version": "3.4.4", + "name": "sebastian/cli-parser", + "version": "2.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", - "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.6 || ^7.0", - "phpunit/php-text-template": "^1.2", - "sebastian/exporter": "^1.2 || ^2.0" - }, - "conflict": { - "phpunit/phpunit": "<5.4.0" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^5.4" - }, - "suggest": { - "ext-soap": "*" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -702,43 +711,49 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "abandoned": true, - "time": "2017-06-30T09:13:00+00:00" + "time": "2024-03-02T07:12:49+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", + "name": "sebastian/code-unit", + "version": "2.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -753,39 +768,48 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" }, { - "name": "sebastian/comparator", - "version": "1.2.4", + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2 || ~2.0" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -798,56 +822,53 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "time": "2017-01-29T09:50:25+00:00" + "time": "2023-02-03T06:59:15+00:00" }, { - "name": "sebastian/diff", - "version": "1.4.3", + "name": "sebastian/comparator", + "version": "5.0.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -860,46 +881,207 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" - } + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.5" + }, + "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:25:16+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68ff824baeae169ec9f2137158ee529584553799" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:37:17+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } ], "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "diff" + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "time": "2017-05-22T07:24:03+00:00" + "time": "2024-03-02T07:15:17+00:00" }, { "name": "sebastian/environment", - "version": "2.0.0", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", - "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^5.0" + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -918,40 +1100,51 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", "hhvm" ], - "time": "2016-11-26T07:53:53+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-23T08:47:14+00:00" }, { "name": "sebastian/exporter", - "version": "2.0.0", + "version": "5.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + "reference": "0735b90f4da94969541dac1da743446e276defa6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", - "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0735b90f4da94969541dac1da743446e276defa6", + "reference": "0735b90f4da94969541dac1da743446e276defa6", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~2.0" + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -964,6 +1157,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -972,54 +1169,73 @@ "name": "Volker Dusch", "email": "github@wallbash.com" }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, { "name": "Adam Harvey", "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], - "time": "2016-11-19T08:54:04+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:09:11+00:00" }, { "name": "sebastian/global-state", - "version": "1.1.1", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" + "ext-dom": "*", + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1038,37 +1254,48 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], - "time": "2015-10-12T03:26:01+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:19:19+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "2.0.1", + "name": "sebastian/lines-of-code", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", - "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", "shasum": "" }, "require": { - "php": ">=5.6", - "sebastian/recursion-context": "~2.0" + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "~5" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -1083,37 +1310,51 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-02-18T15:18:39+00:00" + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:38:20+00:00" }, { - "name": "sebastian/recursion-context", - "version": "2.0.0", + "name": "sebastian/object-enumerator", + "version": "5.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", - "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1126,44 +1367,49 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" - }, + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "url": "https://github.com/sebastianbergmann", + "type": "github" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2016-11-19T07:33:16+00:00" + "time": "2023-02-03T07:08:32+00:00" }, { - "name": "sebastian/resource-operations", - "version": "1.0.0", + "name": "sebastian/object-reflector", + "version": "3.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", "shasum": "" }, "require": { - "php": ">=5.6.0" + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1181,31 +1427,44 @@ "email": "sebastian@phpunit.de" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" }, { - "name": "sebastian/version", - "version": "2.0.1", + "name": "sebastian/recursion-context", + "version": "5.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/47e34210757a2f37a97dcd207d032e1b01e64c7a", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1220,236 +1479,291 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2025-08-10T07:50:56+00:00" }, { - "name": "squizlabs/php_codesniffer", - "version": "3.5.3", + "name": "sebastian/type", + "version": "4.0.0", "source": { "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/557a1fc7ac702c66b0bbfe16ab3d55839ef724cb", - "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "^10.0" }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "3.x-dev" + "dev-main": "4.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { - "name": "Greg Sherwood", + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", "role": "lead" } ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "time": "2019-12-04T04:46:47+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.13.1", + "name": "sebastian/version", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", - "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-ctype": "For best performance" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.13-dev" + "dev-main": "4.0-dev" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "time": "2019-11-27T13:56:44+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { - "name": "symfony/yaml", - "version": "v4.4.2", + "name": "squizlabs/php_codesniffer", + "version": "3.13.5", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "a08832b974dd5fafe3085a66d41fe4c84bb2628c" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/a08832b974dd5fafe3085a66d41fe4c84bb2628c", - "reference": "a08832b974dd5fafe3085a66d41fe4c84bb2628c", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0ca86845ce43291e8f5692c7356fccf3bcf02bf4", + "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/console": "<3.4" + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" }, "require-dev": { - "symfony/console": "^3.4|^4.0|^5.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Greg Sherwood", + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" } ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2019-12-10T10:33:21+00:00" + "time": "2025-11-04T16:30:35+00:00" }, { - "name": "webmozart/assert", - "version": "1.6.0", + "name": "theseer/tokenizer", + "version": "1.3.1", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "573381c0a64f155a0d9a23f4b0c797194805b925" + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925", - "reference": "573381c0a64f155a0d9a23f4b0c797194805b925", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "vimeo/psalm": "<3.6.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" } ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } ], - "time": "2019-11-24T13:36:37+00:00" + "time": "2025-11-17T20:03:58+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [] + "platform": { + "php": ">=8.1" + }, + "platform-dev": {}, + "plugin-api-version": "2.9.0" } From 7a660421d2aae42e3227b1c8eb580a86f0af5956 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:06:01 -0300 Subject: [PATCH 03/19] refactor: adjust code --- composer.json | 2 +- example/index.php | 44 +++--- src/TreeWalker.php | 157 ++++++++-------------- tests/TreeWalkerTest.php | 284 +++++++++++++++------------------------ 4 files changed, 192 insertions(+), 295 deletions(-) diff --git a/composer.json b/composer.json index 451b199..5116ff4 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ }, "autoload": { "psr-4": { - "Lukascivil\\TreeWalker\\": "src/" + "": "src/" } }, "scripts": { diff --git a/example/index.php b/example/index.php index e1bcfb8..c1b1cc4 100644 --- a/example/index.php +++ b/example/index.php @@ -2,38 +2,36 @@ require_once __DIR__ . '/../vendor/autoload.php'; -use Lukascivil\TreeWalker\TreeWalker; - -$treewalker = new TreeWalker([ - 'debug' => true, - 'returntype' => 'jsonstring', -]); +$treewalker = new TreeWalker(array( + "debug" => true, + "returntype" => "jsonstring" +)); $struct1 = file_get_contents(__DIR__ . '/json/json1.json'); $struct2 = json_decode(file_get_contents(__DIR__ . '/json/json2.json'), true); -$struct3 = ['casa' => 1, 'b' => '5', 'cafeina' => ['ss1' => '1', 'ss2' => '2'], 'oi' => 5, '1' => '255']; -$struct4 = ['casa' => 2, 'cafeina' => ['ss' => ['ff' => 21, 'ff1' => 22]], 'oi2' => 5, '1' => '', 'ss' => 'dddddf']; +$struct3 = array("casa" => 1, "b" => "5", "cafeina" => array("ss1" => "1", "ss2" => "2"), "oi" => 5, "1" => "255"); +$struct4 = array("casa" => 2, "cafeina" => array("ss" => array("ff" => 21, "ff1" => 22)), "oi2" => 5, "1" => "", "ss" => "dddddf"); $struct5 = new stdClass(); -$struct5->oi = 's55'; -$struct5->cafe = 'quente'; -$struct5->oi1 = 'oi1'; +$struct5->oi = "s55"; +$struct5->cafe = "quente"; +$struct5->oi1 = "oi1"; class classstruct1 { - public $cafe = 'frio'; + public $cafe = "frio"; } class classstruct2 extends classstruct1 { - public $struct4cc = '2'; + public $struct4cc = "2"; } $struct6 = new classstruct1(); $struct7 = new classstruct2(); -$struct8 = $struct3; -$struct8['cafeina']['ss'] = new classstruct2(); +$struct8 = $struct3; +$struct8["cafeina"]["ss"] = new classstruct2(); // getdiff(modified struct, static struct, slashtostruct) echo "\ngetdiff(modified struct, static struct, slashtostruct)
\n"; @@ -42,31 +40,31 @@ class classstruct2 extends classstruct1 // walker(struct, function) echo "walker(struct, function)
\n"; -print_r($treewalker->walker($struct4, function (array &$struct, $key, &$value): void { - if ($key === 'ff') { +print_r($treewalker->walker($struct4, function (&$struct, $key, &$value) { + if ($key == "ff") { unset($struct[$key]); } - if ($key === 'ff1') { - $value = ['son' => 'tiago']; + if ($key == "ff1") { + $value = array("son" => "tiago"); } })); echo "

\n\n"; // createDynamicallyObjects(struct, newObjectPath) echo "createDynamicallyObjects(struct, newObjectPath)
\n"; -print_r($treewalker->createDynamicallyObjects($struct3, ['cafeina', 'novo'])); +print_r($treewalker->createDynamicallyObjects($struct3, array("cafeina", "novo"))); echo "

\n\n"; // getDynamicallyValue(struct, path) echo "getDynamicallyValue(struct, path)
\n"; -$dynamicpath = ['cafeina', 'ss']; +$dynamicpath = array("cafeina", "ss"); print_r($treewalker->getDynamicallyValue($struct4, $dynamicpath)); echo "
\n\n"; // setDynamicallyValue(struct, path, value) echo "setDynamicallyValue(struct, path, value)
\n"; -$dynamicpath = ['cafeina', 'ss']; -print_r($treewalker->setDynamicallyValue($struct4, $dynamicpath, 'newvalue')); +$dynamicpath = array("cafeina", "ss"); +print_r($treewalker->setDynamicallyValue($struct4, $dynamicpath, "newvalue")); echo "
\n\n"; // structMerge(struct1, struct2, slashtostruct) diff --git a/src/TreeWalker.php b/src/TreeWalker.php index c7a730b..fb29e6b 100644 --- a/src/TreeWalker.php +++ b/src/TreeWalker.php @@ -36,9 +36,7 @@ class TreeWalker private $time_end = 0; /** - * [__construct Class] - * - * @param [array] $config [associative array configuration] + * @param array $config */ public function __construct($config) { @@ -48,9 +46,9 @@ public function __construct($config) } /** - * @param [\stdClass|string|array] $struct [Structure] - * @param [array] $keypath_array [Array with the keys to access dynamically] - * @return [\stdClass|string|array] + * @param \stdClass|string|array $struct + * @param array $keypath_array + * @return \stdClass|string|array */ public function getDynamicallyValue($struct, $keypath_array) { @@ -59,18 +57,16 @@ public function getDynamicallyValue($struct, $keypath_array) } $getDynamically = function ($struct_assocarray, $keypath_array) use (&$getDynamically) { - - if (empty($keypath_array)) { // -> Stop Recursion + if (empty($keypath_array)) { return $struct_assocarray; } - + $key = array_shift($keypath_array); - + if (is_array($struct_assocarray)) { if (array_key_exists($key, $struct_assocarray)) { return $getDynamically($struct_assocarray[$key], $keypath_array); } else { - echo "error"; return '{"error": "Error, some key does not exist!"}'; } } @@ -82,10 +78,10 @@ public function getDynamicallyValue($struct, $keypath_array) } /** - * @param [\stdClass|string|array] $struct [Structure] - * @param [array] $keypath_array [Array with the keys to access dynamically] - * @param [boolean] $value [Simple path with slashs or nested structures] - * @return [\stdClass|string|array] + * @param \stdClass|string|array $struct + * @param array $keypath_array + * @param mixed $value + * @return \stdClass|string|array */ public function setDynamicallyValue($struct, $keypath_array, $value = "") { @@ -94,15 +90,15 @@ public function setDynamicallyValue($struct, $keypath_array, $value = "") } $setDynamically = function (&$struct_assocarray, $keypath_array, $value) use (&$setDynamically) { - if (sizeof($keypath_array) == 1) { // -> Stop Recursion + if (count($keypath_array) === 1) { $struct_assocarray[$keypath_array[0]] = $value; + return; } $key = array_shift($keypath_array); if (is_array($struct_assocarray)) { if (array_key_exists($key, $struct_assocarray)) { - //echo sizeof($keypath_array); return $setDynamically($struct_assocarray[$key], $keypath_array, $value); } else { return '{"error": "Error, some key does not exist!"}'; @@ -116,11 +112,9 @@ public function setDynamicallyValue($struct, $keypath_array, $value = "") } /** - * [Create nested obj Dynamically if(key exist || key !exist), by $path_string - * - * @param [array|string|\stdClass] $struct1 [Structure] - * @param [array] $keypath_array [Array with the keys that will be created] - * @return [array|string|\stdClass] New structure + * @param array|string|\stdClass $struct + * @param array $keypath_array + * @return array|string|\stdClass */ public function createDynamicallyObjects($struct, $keypath_array) { @@ -135,21 +129,19 @@ public function createDynamicallyObjects($struct, $keypath_array) $path_string .= $key . "/"; } - $this->accessDynamically($path_string, $struct); // cria + $this->accessDynamically($path_string, $struct); return $this->returnTypeConvert($struct); } /** - * [This function enables you to dynamically access the value of a structure] - * - * @param [string] $path_string [path] - * @param [array] $array current [array] + * @param string $path_string + * @param array $array */ private function accessDynamically($path_string, &$array) { $keys = explode('/', substr_replace($path_string, "", -1)); $ref = &$array; - + foreach ($keys as $key => $value) { $ref = &$ref[$value]; } @@ -157,18 +149,16 @@ private function accessDynamically($path_string, &$array) } /** - * [walk throughout the structure] - * - * @param [array|string|\stdClass] $struct [Structure] - * @param [function] $callback [The function will always be called when walking through the nodes] - * @return [array|string|\stdClass] Input structure + * @param array|string|\stdClass $struct + * @param callable $callback + * @return array|string|\stdClass */ public function walker(&$struct, $callback) { if (!$this->studyType($struct, $problem)) { return $problem; } - + $this->clockStart(); $replaceWalker = function (&$struct, $callback) use (&$replaceWalker) { @@ -177,18 +167,14 @@ public function walker(&$struct, $callback) foreach ($struct as $key => &$value) { $callback($struct, $key, $value); - if (isset($struct[$key])) { - if (is_array($struct[$key])) { - $replaceWalker($value, $callback); - } else { - } + if (isset($struct[$key]) && is_array($struct[$key])) { + $replaceWalker($value, $callback); } } } return $struct; }; - // Call the recursive method to walk in the struct $replaced_array = $replaceWalker($struct, $callback); if ($this->config["debug"]) { @@ -199,11 +185,10 @@ public function walker(&$struct, $callback) } /** - * Returns the difference between two structures - * - * @param [array|string|\stdClass] $struct1 [struct1] - * @param [array|string|\stdClass] $struct2 [struct2] - * @return [array|string|\stdClass] struct diff + * @param array|string|\stdClass $struct1 + * @param array|string|\stdClass $struct2 + * @param bool $slashtoobject + * @return array|string|\stdClass */ public function getdiff($struct1, $struct2, $slashtoobject = false) { @@ -228,15 +213,9 @@ public function getdiff($struct1, $struct2, $slashtoobject = false) } /** - * [Returns a array with all the possible paths of the structure -> &$array. - * There is several ways to do this and i believe it's not the best way, - * but I chose this way, separately(structPathArray() + structPathArrayDiff()), - * to be more didactic. - * In the middle of recursion I could already make comparisons could be faster.] - * - * @param [array] $assocarray [Structure already standardized as associative array to get performance*] - * @param [array] &$array [Array paths created from the structure] - * @param [string] $currentpath [Current path] + * @param array $assocarray + * @param array &$array + * @param string $currentpath */ private function structPathArray($assocarray, &$array, $currentpath) { @@ -248,7 +227,7 @@ private function structPathArray($assocarray, &$array, $currentpath) if (gettype($assocarray[$key]) == "array" && !empty($assocarray[$key])) { $this->structPathArray($assocarray[$key], $array, $path); } elseif (gettype($assocarray[$key]) == "object") { - if (!empty((array)$assocarray[$key])) { // Force Casting (array)Obj + if (!empty((array)$assocarray[$key])) { $this->structPathArray((array)$assocarray[$key], $array, $path); } else { $array[$path] = array(); @@ -264,15 +243,13 @@ private function structPathArray($assocarray, &$array, $currentpath) } /** - * [Join two structures] - * - * @param [array|string|\stdClass] $struct1 [Structure] - * @param [array|string|\stdClass] $struct2 [Structure] - * @return [array|string|\stdClass] [The union of structures] + * @param array|string|\stdClass $struct1 + * @param array|string|\stdClass $struct2 + * @param bool $slashtoobject + * @return array|string|\stdClass */ public function structMerge($struct1, $struct2, $slashtoobject = false) { - if (!$this->studyType($struct1, $problem) || !$this->studyType($struct2, $problem)) { return $problem; } @@ -285,7 +262,7 @@ public function structMerge($struct1, $struct2, $slashtoobject = false) $this->structPathArray($struct1, $structpath1_array, ""); $this->structPathArray($struct2, $structpath2_array, ""); $merged_array = array_merge($structpath2_array, $structpath1_array); - + if ($this->config["debug"]) { $merged_array["time"] = $this->clockMark(); } @@ -298,10 +275,8 @@ public function structMerge($struct1, $struct2, $slashtoobject = false) } /** - * [Convert the slashs to nested structures] - * - * @param [type] $assocarray [Associative array to convert the keys] - * @return [array] [No slashs on key] + * @param array $assocarray + * @return array */ private function pathSlashToStruct($assocarray) { @@ -335,12 +310,10 @@ private function pathSlashToStruct($assocarray) } /** - * [Returns a structure with the news] - * - * @param [array] $structpath1_array [Vector paths of structure 1] - * @param [array] $structpath2_array [Vector paths of structure 2] - * @param [boolean] $slashtoobject [Simple path with slashs or nested structures] - * @return [array] [Delta array] + * @param array $structpath1_array + * @param array $structpath2_array + * @param bool $slashtoobject + * @return array */ private function structPathArrayDiff($structpath1_array, $structpath2_array, $slashtoobject) { @@ -373,7 +346,7 @@ private function structPathArrayDiff($structpath1_array, $structpath2_array, $sl } if ($slashtoobject) { - foreach ($deltadiff_array as $key => &$value) { //the length will be always 3, [new, removed, edited] + foreach ($deltadiff_array as $key => &$value) { $value = $this->pathSlashToStruct($value); } } @@ -382,10 +355,8 @@ private function structPathArrayDiff($structpath1_array, $structpath2_array, $sl } /** - * [Returns a converted structure] - * - * @param [array|string|\stdClass] $struct [Structure for converting] - * @return [array|string|\stdClass] [Converted structure] + * @param array|string|\stdClass $struct + * @return array|string|\stdClass */ private function returnTypeConvert($struct) { @@ -403,17 +374,15 @@ private function returnTypeConvert($struct) return $struct; break; default: - return "returntype não é valido!"; + return "returntype is not valid!"; break; } } /** - * [analyzes the structure] - * - * @param [array|string|\stdClass] &$struct [Structure] - * @param [string] &$problem [If there is a problem with the structure , it will be returned] - * @return [type] [true->Everything is ok, false->Error] + * @param array|string|\stdClass &$struct + * @param string &$problem + * @return bool */ private function studyType(&$struct, &$problem) { @@ -432,41 +401,33 @@ private function studyType(&$struct, &$problem) } /** - * [checks if the string is a valid json] - * - * @param [string] $string [Json string?] - * @return boolean [true->Everything is ok, false->Error] + * @param mixed $string + * @return bool */ private function isJsonString($string) { if (!is_string($string)) { return false; - } else { - return (json_last_error() == JSON_ERROR_NONE); } + + json_decode($string); + + return json_last_error() === JSON_ERROR_NONE; } - /** - * [Starts the clock] - */ private function clockStart() { $this->time_start = round(microtime(true) * 1000); } /** - * [Marks the current time] - * - * @return [String] Time in milliseconds + * @return string */ private function clockMark() { return round(microtime(true) * 1000) - $this->time_start . " milliseconds"; } - /** - * [switch the type] - */ private function switchType() { $aux = $this->config["returntype"]; diff --git a/tests/TreeWalkerTest.php b/tests/TreeWalkerTest.php index 0f1a82a..ff3e57b 100644 --- a/tests/TreeWalkerTest.php +++ b/tests/TreeWalkerTest.php @@ -1,8 +1,5 @@ false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array( + "debug" => false, + "returntype" => "array" + )); - $struct1 = ['1' => ['2' => '7', '3' => ['4' => '6']]]; - $struct2 = ['1' => ['3' => ['4' => '5']]]; + $struct1 = array('1' => array('2' => '7', '3' => array('4' => '6'))); + $struct2 = array('1' => array('3' => array('4' => '5'))); - $expected = [ - 'edited' => ['1/3/4' => ['newvalue' => '5', 'oldvalue' => '6']], - 'new' => [], - 'removed' => ['1/2' => '7'], - ]; + $expectedResult = array( + 'edited' => array('1/3/4' => array('newvalue' => '5', 'oldvalue' => '6')), + 'new' => array(), + 'removed' => array('1/2' => '7') + ); - $this->assertEquals($expected, $tw->getdiff($struct2, $struct1, false)); + $this->assertEquals($expectedResult, $treewalker->getdiff($struct2, $struct1, false)); } public function testGetdiffWithArrayProperty(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); - - $struct1 = ['a' => 1, 'b' => [['c1' => 1], ['c2' => 2]]]; - $struct2 = ['a' => 11, 'b' => [['c1' => 1], ['c2' => 22]]]; - - $expected = [ - 'edited' => [ - 'a' => ['newvalue' => 11, 'oldvalue' => 1], - 'b/1/c2' => ['newvalue' => 22, 'oldvalue' => 2], - ], - 'new' => [], - 'removed' => [], - ]; - - $this->assertEquals($expected, $tw->getdiff($struct2, $struct1, false)); + $treewalker = new TreeWalker(array( + "debug" => false, + "returntype" => "array" + )); + + $struct1 = array('a' => 1, 'b' => array(array('c1' => 1), array('c2' => 2))); + $struct2 = array('a' => 11, 'b' => array(array('c1' => 1), array('c2' => 22))); + + $expectedResult = array( + 'edited' => array( + 'a' => array('newvalue' => 11, 'oldvalue' => 1), + 'b/1/c2' => array('newvalue' => 22, 'oldvalue' => 2) + ), + 'new' => array(), + 'removed' => array() + ); + + $this->assertEquals($expectedResult, $treewalker->getdiff($struct2, $struct1, false)); } public function testGetdiffWithDifferentTypes(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); - - $struct1 = ['a' => 1, 'b' => ['c1' => 2], 'c' => 3]; - $struct2 = ['a' => '1', 'b' => 2, 'c' => true]; - - $expected = [ - 'edited' => [ - 'a' => ['newvalue' => '1', 'oldvalue' => 1], - 'c' => ['newvalue' => true, 'oldvalue' => 3], - ], - 'new' => ['b' => 2], - 'removed' => ['b/c1' => 2], - ]; - - $this->assertEquals($expected, $tw->getdiff($struct2, $struct1, false)); + $treewalker = new TreeWalker(array( + "debug" => false, + "returntype" => "array" + )); + + $struct1 = array('a' => 1, 'b' => array('c1' => 2), 'c' => 3); + $struct2 = array('a' => '1', 'b' => 2, 'c' => true); + + $expectedResult = array( + 'edited' => array( + 'a' => array('newvalue' => '1', 'oldvalue' => 1), + 'c' => array('newvalue' => true, 'oldvalue' => 3) + ), + 'new' => array('b' => 2), + 'removed' => array('b/c1' => 2) + ); + + $this->assertEquals($expectedResult, $treewalker->getdiff($struct2, $struct1, false)); } - public function testGetdiffSlashToObject(): void + public function testGetdiffWithJsonInput(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $struct1 = ['a' => ['b' => 1]]; - $struct2 = ['a' => ['b' => 2]]; - - $result = $tw->getdiff($struct1, $struct2, true); + $result = $treewalker->getdiff('{"a":1,"b":2}', '{"a":1,"b":3}', false); $this->assertArrayHasKey('edited', $result); - $this->assertArrayHasKey('a', $result['edited']); - $this->assertArrayHasKey('b', $result['edited']['a']); + $this->assertArrayHasKey('b', $result['edited']); + $this->assertEquals(3, $result['edited']['b']['oldvalue']); + $this->assertEquals(2, $result['edited']['b']['newvalue']); } - public function testGetdiffWithJsonStringInput(): void + public function testGetdiffWithObjectInput(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $json1 = '{"a": 1, "b": 2}'; - $json2 = '{"a": 1, "b": 3}'; - - $result = $tw->getdiff($json1, $json2, false); + $result = $treewalker->getdiff((object)array('a' => 1, 'b' => 2), (object)array('a' => 1, 'b' => 3), false); $this->assertArrayHasKey('edited', $result); $this->assertArrayHasKey('b', $result['edited']); - $this->assertEquals(3, $result['edited']['b']['oldvalue']); - $this->assertEquals(2, $result['edited']['b']['newvalue']); } - public function testGetdiffWithObjectInput(): void + public function testGetdiffSlashToObject(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); - - $struct1 = (object) ['a' => 1, 'b' => 2]; - $struct2 = (object) ['a' => 1, 'b' => 3]; + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $result = $tw->getdiff($struct1, $struct2, false); + $result = $treewalker->getdiff(array('a' => array('b' => 1)), array('a' => array('b' => 2)), true); $this->assertArrayHasKey('edited', $result); - $this->assertArrayHasKey('b', $result['edited']); + $this->assertArrayHasKey('a', $result['edited']); + $this->assertArrayHasKey('b', $result['edited']['a']); } - // ------------------------------------------------------------------------- - // getdiff return types - // ------------------------------------------------------------------------- - public function testGetdiffReturnsJsonString(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'jsonstring']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "jsonstring")); - $result = $tw->getdiff(['a' => 1], ['a' => 2], false); + $result = $treewalker->getdiff(array('a' => 1), array('a' => 2), false); $this->assertIsString($result); $this->assertIsArray(json_decode($result, true)); @@ -123,9 +116,9 @@ public function testGetdiffReturnsJsonString(): void public function testGetdiffReturnsObject(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'object']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "object")); - $result = $tw->getdiff(['a' => 1], ['a' => 2], false); + $result = $treewalker->getdiff(array('a' => 1), array('a' => 2), false); $this->assertIsObject($result); $this->assertObjectHasProperty('edited', $result); @@ -137,35 +130,27 @@ public function testGetdiffReturnsObject(): void public function testGetDynamicallyValueReturnsScalar(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $struct = ['a' => ['b' => ['c' => 42]]]; + $struct = array('a' => array('b' => array('c' => 42))); - $this->assertEquals(42, $tw->getDynamicallyValue($struct, ['a', 'b', 'c'])); + $this->assertEquals(42, $treewalker->getDynamicallyValue($struct, array('a', 'b', 'c'))); } public function testGetDynamicallyValueReturnsNestedArray(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $struct = ['a' => ['b' => ['x' => 1, 'y' => 2]]]; + $struct = array('a' => array('b' => array('x' => 1, 'y' => 2))); - $this->assertEquals(['x' => 1, 'y' => 2], $tw->getDynamicallyValue($struct, ['a', 'b'])); + $this->assertEquals(array('x' => 1, 'y' => 2), $treewalker->getDynamicallyValue($struct, array('a', 'b'))); } public function testGetDynamicallyValueWithJsonInput(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $this->assertEquals(99, $tw->getDynamicallyValue('{"a": {"b": 99}}', ['a', 'b'])); - } - - public function testGetDynamicallyValueThrowsOnMissingKey(): void - { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); - - $this->expectException(\RuntimeException::class); - $tw->getDynamicallyValue(['a' => ['b' => 1]], ['a', 'missing']); + $this->assertEquals(99, $treewalker->getDynamicallyValue('{"a":{"b":99}}', array('a', 'b'))); } // ------------------------------------------------------------------------- @@ -174,101 +159,78 @@ public function testGetDynamicallyValueThrowsOnMissingKey(): void public function testSetDynamicallyValueUpdatesNestedKey(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $struct = ['a' => ['b' => 1]]; - $result = $tw->setDynamicallyValue($struct, ['a', 'b'], 99); + $struct = array('a' => array('b' => 1)); + $result = $treewalker->setDynamicallyValue($struct, array('a', 'b'), 99); - $this->assertEquals(['a' => ['b' => 99]], $result); + $this->assertEquals(array('a' => array('b' => 99)), $result); } public function testSetDynamicallyValueDoesNotMutateOriginal(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $struct = ['a' => ['b' => 1]]; - $tw->setDynamicallyValue($struct, ['a', 'b'], 99); + $struct = array('a' => array('b' => 1)); + $treewalker->setDynamicallyValue($struct, array('a', 'b'), 99); $this->assertEquals(1, $struct['a']['b']); } - public function testSetDynamicallyValueThrowsOnMissingKey(): void - { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); - - $this->expectException(\RuntimeException::class); - $tw->setDynamicallyValue(['a' => ['b' => 1]], ['a', 'missing', 'deep'], 5); - } - // ------------------------------------------------------------------------- // createDynamicallyObjects // ------------------------------------------------------------------------- public function testCreateDynamicallyObjectsOnEmptyStruct(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $result = $tw->createDynamicallyObjects([], ['level1', 'level2']); + $result = $treewalker->createDynamicallyObjects(array(), array('level1', 'level2')); - $this->assertEquals(['level1' => ['level2' => []]], $result); + $this->assertEquals(array('level1' => array('level2' => array())), $result); } public function testCreateDynamicallyObjectsAddsToExistingStruct(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $struct = ['existing' => 1]; - $result = $tw->createDynamicallyObjects($struct, ['new', 'path']); + $struct = array('existing' => 1); + $result = $treewalker->createDynamicallyObjects($struct, array('new', 'path')); $this->assertArrayHasKey('existing', $result); - $this->assertArrayHasKey('new', $result); - $this->assertEquals([], $result['new']['path']); + $this->assertEquals(array(), $result['new']['path']); } // ------------------------------------------------------------------------- // walker // ------------------------------------------------------------------------- - public function testWalkerMultipliesIntValues(): void + public function testWalkerModifiesValues(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $struct = ['a' => 1, 'b' => 2, 'c' => ['d' => 3]]; - $result = $tw->walker($struct, function (array &$node, $key, &$value): void { + $struct = array('a' => 1, 'b' => 2, 'c' => array('d' => 3)); + $result = $treewalker->walker($struct, function (&$struct, $key, &$value) { if (is_int($value)) { $value = $value * 2; } }); - $this->assertEquals(['a' => 2, 'b' => 4, 'c' => ['d' => 6]], $result); + $this->assertEquals(array('a' => 2, 'b' => 4, 'c' => array('d' => 6)), $result); } public function testWalkerDeletesNode(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $struct = ['a' => 1, 'b' => 2, 'c' => 3]; - $result = $tw->walker($struct, function (array &$node, $key, &$value): void { + $struct = array('a' => 1, 'b' => 2, 'c' => 3); + $result = $treewalker->walker($struct, function (&$struct, $key, &$value) { if ($key === 'b') { - unset($node[$key]); - } - }); - - $this->assertEquals(['a' => 1, 'c' => 3], $result); - } - - public function testWalkerWithJsonInput(): void - { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); - - $struct = '{"x": 10, "y": 20}'; - $result = $tw->walker($struct, function (array &$node, $key, &$value): void { - if (is_int($value)) { - $value = 0; + unset($struct[$key]); } }); - $this->assertEquals(['x' => 0, 'y' => 0], $result); + $this->assertEquals(array('a' => 1, 'c' => 3), $result); } // ------------------------------------------------------------------------- @@ -277,39 +239,27 @@ public function testWalkerWithJsonInput(): void public function testStructMergeFirstOverridesSecond(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $struct1 = ['a' => 1, 'b' => 2]; - $struct2 = ['b' => 99, 'c' => 3]; + $struct1 = array('a' => 1, 'b' => 2); + $struct2 = array('b' => 99, 'c' => 3); - $result = $tw->structMerge($struct1, $struct2, false); + $result = $treewalker->structMerge($struct1, $struct2, false); $this->assertEquals(1, $result['a']); - $this->assertEquals(2, $result['b']); // struct1 wins + $this->assertEquals(2, $result['b']); $this->assertEquals(3, $result['c']); } - public function testStructMergeFlattensNestedStructs(): void - { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); - - $struct1 = ['a' => ['b' => 1]]; - $struct2 = ['a' => ['c' => 2]]; - - $result = $tw->structMerge($struct1, $struct2, false); - - $this->assertArrayHasKey('a/b', $result); - $this->assertArrayHasKey('a/c', $result); - } - public function testStructMergeSlashToObject(): void { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'array']); - - $struct1 = ['a' => ['b' => 1]]; - $struct2 = ['a' => ['c' => 2]]; + $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $result = $tw->structMerge($struct1, $struct2, true); + $result = $treewalker->structMerge( + array('a' => array('b' => 1)), + array('a' => array('c' => 2)), + true + ); $this->assertArrayHasKey('a', $result); $this->assertArrayHasKey('b', $result['a']); @@ -322,23 +272,11 @@ public function testStructMergeSlashToObject(): void public function testDebugModeAddsTimeKey(): void { - $tw = new TreeWalker(['debug' => true, 'returntype' => 'array']); + $treewalker = new TreeWalker(array("debug" => true, "returntype" => "array")); - $result = $tw->getdiff(['a' => 1], ['a' => 2], false); + $result = $treewalker->getdiff(array('a' => 1), array('a' => 2), false); $this->assertArrayHasKey('time', $result); $this->assertStringContainsString('milliseconds', $result['time']); } - - // ------------------------------------------------------------------------- - // invalid input - // ------------------------------------------------------------------------- - - public function testInvalidReturnTypeThrows(): void - { - $tw = new TreeWalker(['debug' => false, 'returntype' => 'invalid']); - - $this->expectException(\InvalidArgumentException::class); - $tw->getdiff(['a' => 1], ['a' => 2], false); - } } From 4730fbccc86ab6e0243bddf05dc8ea29b935e5a4 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:10:43 -0300 Subject: [PATCH 04/19] Update php.yml --- .github/workflows/php.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index c2ee90d..152133f 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ["8.1", "8.2", "8.3"] + php-version: ["8.1", "8.5"] steps: - uses: actions/checkout@v4 From 9e515a7c5ae87db11f39f6a295e891386f3207b3 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:13:58 -0300 Subject: [PATCH 05/19] Update php.yml --- .github/workflows/php.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 152133f..b6caadf 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -10,7 +10,7 @@ jobs: php-version: ["8.1", "8.5"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup PHP with Xdebug uses: shivammathur/setup-php@v2 @@ -28,8 +28,8 @@ jobs: run: composer run-script test - name: Upload coverage to Codecov - if: matrix.php-version == '8.3' - uses: codecov/codecov-action@v4 + if: matrix.php-version == '8.5' + uses: codecov/codecov-action@v6 with: token: ${{ secrets.CODECOV_TOKEN }} file: ./coverage.xml From 9299bc6da5ebab713cba5a21742163795f5301dc Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:15:14 -0300 Subject: [PATCH 06/19] Update TreeWalker.php --- src/TreeWalker.php | 190 ++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/src/TreeWalker.php b/src/TreeWalker.php index fb29e6b..58a3585 100644 --- a/src/TreeWalker.php +++ b/src/TreeWalker.php @@ -31,9 +31,9 @@ class TreeWalker "returntype" => "jsonstring" ); - private $typetowork = "array"; - private $time_start = 0; - private $time_end = 0; + private $typeToWork = "array"; + private $timeStart = 0; + private $timeEnd = 0; /** * @param array $config @@ -47,99 +47,99 @@ public function __construct($config) /** * @param \stdClass|string|array $struct - * @param array $keypath_array + * @param array $keypathArray * @return \stdClass|string|array */ - public function getDynamicallyValue($struct, $keypath_array) + public function getDynamicallyValue($struct, $keypathArray) { if (!$this->studyType($struct, $problem)) { return $problem; } - $getDynamically = function ($struct_assocarray, $keypath_array) use (&$getDynamically) { - if (empty($keypath_array)) { - return $struct_assocarray; + $getDynamically = function ($structAssocarray, $keypathArray) use (&$getDynamically) { + if (empty($keypathArray)) { + return $structAssocarray; } - $key = array_shift($keypath_array); + $key = array_shift($keypathArray); - if (is_array($struct_assocarray)) { - if (array_key_exists($key, $struct_assocarray)) { - return $getDynamically($struct_assocarray[$key], $keypath_array); + if (is_array($structAssocarray)) { + if (array_key_exists($key, $structAssocarray)) { + return $getDynamically($structAssocarray[$key], $keypathArray); } else { return '{"error": "Error, some key does not exist!"}'; } } }; - $value = $getDynamically($struct, $keypath_array); + $value = $getDynamically($struct, $keypathArray); return $this->returnTypeConvert($value); } /** * @param \stdClass|string|array $struct - * @param array $keypath_array + * @param array $keypathArray * @param mixed $value * @return \stdClass|string|array */ - public function setDynamicallyValue($struct, $keypath_array, $value = "") + public function setDynamicallyValue($struct, $keypathArray, $value = "") { if (!$this->studyType($struct, $problem)) { return $problem; } - $setDynamically = function (&$struct_assocarray, $keypath_array, $value) use (&$setDynamically) { - if (count($keypath_array) === 1) { - $struct_assocarray[$keypath_array[0]] = $value; + $setDynamically = function (&$structAssocarray, $keypathArray, $value) use (&$setDynamically) { + if (count($keypathArray) === 1) { + $structAssocarray[$keypathArray[0]] = $value; return; } - $key = array_shift($keypath_array); + $key = array_shift($keypathArray); - if (is_array($struct_assocarray)) { - if (array_key_exists($key, $struct_assocarray)) { - return $setDynamically($struct_assocarray[$key], $keypath_array, $value); + if (is_array($structAssocarray)) { + if (array_key_exists($key, $structAssocarray)) { + return $setDynamically($structAssocarray[$key], $keypathArray, $value); } else { return '{"error": "Error, some key does not exist!"}'; } } }; - $setDynamically($struct, $keypath_array, $value); + $setDynamically($struct, $keypathArray, $value); return $this->returnTypeConvert($struct); } /** * @param array|string|\stdClass $struct - * @param array $keypath_array + * @param array $keypathArray * @return array|string|\stdClass */ - public function createDynamicallyObjects($struct, $keypath_array) + public function createDynamicallyObjects($struct, $keypathArray) { if (!$this->studyType($struct, $problem)) { return $problem; } - $path_string = ""; + $pathString = ""; - for ($i = 0; $i < count($keypath_array); $i++) { - $key = $keypath_array[$i]; - $path_string .= $key . "/"; + for ($i = 0; $i < count($keypathArray); $i++) { + $key = $keypathArray[$i]; + $pathString .= $key . "/"; } - $this->accessDynamically($path_string, $struct); + $this->accessDynamically($pathString, $struct); return $this->returnTypeConvert($struct); } /** - * @param string $path_string + * @param string $pathString * @param array $array */ - private function accessDynamically($path_string, &$array) + private function accessDynamically($pathString, &$array) { - $keys = explode('/', substr_replace($path_string, "", -1)); + $keys = explode('/', substr_replace($pathString, "", -1)); $ref = &$array; foreach ($keys as $key => $value) { @@ -175,13 +175,13 @@ public function walker(&$struct, $callback) return $struct; }; - $replaced_array = $replaceWalker($struct, $callback); + $replacedArray = $replaceWalker($struct, $callback); if ($this->config["debug"]) { - $replaced_array["time"] = $this->clockMark(); + $replacedArray["time"] = $this->clockMark(); } - return $this->returnTypeConvert($replaced_array); + return $this->returnTypeConvert($replacedArray); } /** @@ -198,37 +198,37 @@ public function getdiff($struct1, $struct2, $slashtoobject = false) $this->clockStart(); - $structpath1_array = array(); - $structpath2_array = array(); + $structPath1Array = array(); + $structPath2Array = array(); - $this->structPathArray($struct1, $structpath1_array, ""); - $this->structPathArray($struct2, $structpath2_array, ""); - $deltadiff_array = $this->structPathArrayDiff($structpath1_array, $structpath2_array, $slashtoobject); + $this->structPathArray($struct1, $structPath1Array, ""); + $this->structPathArray($struct2, $structPath2Array, ""); + $deltaDiffArray = $this->structPathArrayDiff($structPath1Array, $structPath2Array, $slashtoobject); if ($this->config["debug"]) { - $deltadiff_array["time"] = $this->clockMark(); + $deltaDiffArray["time"] = $this->clockMark(); } - return $this->returnTypeConvert($deltadiff_array); + return $this->returnTypeConvert($deltaDiffArray); } /** - * @param array $assocarray + * @param array $assocArray * @param array &$array - * @param string $currentpath + * @param string $currentPath */ - private function structPathArray($assocarray, &$array, $currentpath) + private function structPathArray($assocArray, &$array, $currentPath) { - if (is_array($assocarray)) { - foreach ($assocarray as $key => $value) { - if (array_key_exists($key, $assocarray)) { - $path = $currentpath !== '' ? $currentpath . "/" . $key : sprintf($key); - - if (gettype($assocarray[$key]) == "array" && !empty($assocarray[$key])) { - $this->structPathArray($assocarray[$key], $array, $path); - } elseif (gettype($assocarray[$key]) == "object") { - if (!empty((array)$assocarray[$key])) { - $this->structPathArray((array)$assocarray[$key], $array, $path); + if (is_array($assocArray)) { + foreach ($assocArray as $key => $value) { + if (array_key_exists($key, $assocArray)) { + $path = $currentPath !== '' ? $currentPath . "/" . $key : sprintf($key); + + if (gettype($assocArray[$key]) == "array" && !empty($assocArray[$key])) { + $this->structPathArray($assocArray[$key], $array, $path); + } elseif (gettype($assocArray[$key]) == "object") { + if (!empty((array)$assocArray[$key])) { + $this->structPathArray((array)$assocArray[$key], $array, $path); } else { $array[$path] = array(); } @@ -256,102 +256,102 @@ public function structMerge($struct1, $struct2, $slashtoobject = false) $this->clockStart(); - $structpath1_array = array(); - $structpath2_array = array(); + $structPath1Array = array(); + $structPath2Array = array(); - $this->structPathArray($struct1, $structpath1_array, ""); - $this->structPathArray($struct2, $structpath2_array, ""); - $merged_array = array_merge($structpath2_array, $structpath1_array); + $this->structPathArray($struct1, $structPath1Array, ""); + $this->structPathArray($struct2, $structPath2Array, ""); + $mergedArray = array_merge($structPath2Array, $structPath1Array); if ($this->config["debug"]) { - $merged_array["time"] = $this->clockMark(); + $mergedArray["time"] = $this->clockMark(); } if ($slashtoobject) { - $merged_array = $this->pathSlashToStruct($merged_array); + $mergedArray = $this->pathSlashToStruct($mergedArray); } - return $this->returnTypeConvert($merged_array); + return $this->returnTypeConvert($mergedArray); } /** - * @param array $assocarray + * @param array $assocArray * @return array */ - private function pathSlashToStruct($assocarray) + private function pathSlashToStruct($assocArray) { - $new_assocarray = []; + $newAssocArray = []; $this->switchType(); - if (is_array($assocarray)) { - foreach ($assocarray as $key => $value) { + if (is_array($assocArray)) { + foreach ($assocArray as $key => $value) { if (strpos($key, '/') !== false) { $aux = explode("/", $key); - $newkey = $aux[0]; + $newKey = $aux[0]; array_shift($aux); - if (isset($new_assocarray[$newkey])) { - $new_assocarray[$newkey] = $this->createDynamicallyObjects($new_assocarray[$newkey], $aux); - $new_assocarray[$newkey] = $this->setDynamicallyValue($new_assocarray[$newkey], $aux, $value); + if (isset($newAssocArray[$newKey])) { + $newAssocArray[$newKey] = $this->createDynamicallyObjects($newAssocArray[$newKey], $aux); + $newAssocArray[$newKey] = $this->setDynamicallyValue($newAssocArray[$newKey], $aux, $value); } else { - $new_assocarray[$newkey] = $this->createDynamicallyObjects(array(), $aux); - $new_assocarray[$newkey] = $this->setDynamicallyValue($new_assocarray[$newkey], $aux, $value); + $newAssocArray[$newKey] = $this->createDynamicallyObjects(array(), $aux); + $newAssocArray[$newKey] = $this->setDynamicallyValue($newAssocArray[$newKey], $aux, $value); } } else { - $new_assocarray[$key] = $value; + $newAssocArray[$key] = $value; } } } $this->switchType(); - return $new_assocarray; + return $newAssocArray; } /** - * @param array $structpath1_array - * @param array $structpath2_array + * @param array $structPath1Array + * @param array $structPath2Array * @param bool $slashtoobject * @return array */ - private function structPathArrayDiff($structpath1_array, $structpath2_array, $slashtoobject) + private function structPathArrayDiff($structPath1Array, $structPath2Array, $slashtoobject) { - $deltadiff_array = array( + $deltaDiffArray = array( "new" => array(), "removed" => array(), "edited" => array() ); - foreach ($structpath1_array as $key1 => $value1) { - if (array_key_exists($key1, $structpath2_array)) { - if ($value1 !== $structpath2_array[$key1]) { + foreach ($structPath1Array as $key1 => $value1) { + if (array_key_exists($key1, $structPath2Array)) { + if ($value1 !== $structPath2Array[$key1]) { $edited = array( - "oldvalue" => $structpath2_array[$key1], + "oldvalue" => $structPath2Array[$key1], "newvalue" => $value1 ); - $deltadiff_array["edited"][$key1] = $edited; + $deltaDiffArray["edited"][$key1] = $edited; } } else { - $deltadiff_array["new"][$key1] = $value1; + $deltaDiffArray["new"][$key1] = $value1; } } - $removido = array_diff_key($structpath2_array, $structpath1_array); + $removido = array_diff_key($structPath2Array, $structPath1Array); if (!empty($removido)) { foreach ($removido as $key => $value) { - $deltadiff_array["removed"][$key] = $value; + $deltaDiffArray["removed"][$key] = $value; } } if ($slashtoobject) { - foreach ($deltadiff_array as $key => &$value) { + foreach ($deltaDiffArray as $key => &$value) { $value = $this->pathSlashToStruct($value); } } - return $deltadiff_array; + return $deltaDiffArray; } /** @@ -417,7 +417,7 @@ private function isJsonString($string) private function clockStart() { - $this->time_start = round(microtime(true) * 1000); + $this->timeStart = round(microtime(true) * 1000); } /** @@ -425,13 +425,13 @@ private function clockStart() */ private function clockMark() { - return round(microtime(true) * 1000) - $this->time_start . " milliseconds"; + return round(microtime(true) * 1000) - $this->timeStart . " milliseconds"; } private function switchType() { $aux = $this->config["returntype"]; - $this->config["returntype"] = $this->typetowork; - $this->typetowork = $aux; + $this->config["returntype"] = $this->typeToWork; + $this->typeToWork = $aux; } } From 4ae9d95a6e76ef2d852cf86f311d44777dd7b0b8 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:15:27 -0300 Subject: [PATCH 07/19] Update index.php --- example/index.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/example/index.php b/example/index.php index c1b1cc4..f220029 100644 --- a/example/index.php +++ b/example/index.php @@ -57,14 +57,14 @@ class classstruct2 extends classstruct1 // getDynamicallyValue(struct, path) echo "getDynamicallyValue(struct, path)
\n"; -$dynamicpath = array("cafeina", "ss"); -print_r($treewalker->getDynamicallyValue($struct4, $dynamicpath)); +$dynamicPath = array("cafeina", "ss"); +print_r($treewalker->getDynamicallyValue($struct4, $dynamicPath)); echo "
\n\n"; // setDynamicallyValue(struct, path, value) echo "setDynamicallyValue(struct, path, value)
\n"; -$dynamicpath = array("cafeina", "ss"); -print_r($treewalker->setDynamicallyValue($struct4, $dynamicpath, "newvalue")); +$dynamicPath = array("cafeina", "ss"); +print_r($treewalker->setDynamicallyValue($struct4, $dynamicPath, "newvalue")); echo "
\n\n"; // structMerge(struct1, struct2, slashtostruct) From 856f84b0bb11aa8d23828252122cae34ea64b65d Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:15:46 -0300 Subject: [PATCH 08/19] Update TreeWalkerTest.php --- tests/TreeWalkerTest.php | 80 ++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/TreeWalkerTest.php b/tests/TreeWalkerTest.php index ff3e57b..e9860b6 100644 --- a/tests/TreeWalkerTest.php +++ b/tests/TreeWalkerTest.php @@ -10,7 +10,7 @@ class TreeWalkerTest extends TestCase public function testGetdiffSimpleStructs(): void { - $treewalker = new TreeWalker(array( + $treeWalker = new TreeWalker(array( "debug" => false, "returntype" => "array" )); @@ -24,12 +24,12 @@ public function testGetdiffSimpleStructs(): void 'removed' => array('1/2' => '7') ); - $this->assertEquals($expectedResult, $treewalker->getdiff($struct2, $struct1, false)); + $this->assertEquals($expectedResult, $treeWalker->getdiff($struct2, $struct1, false)); } public function testGetdiffWithArrayProperty(): void { - $treewalker = new TreeWalker(array( + $treeWalker = new TreeWalker(array( "debug" => false, "returntype" => "array" )); @@ -46,12 +46,12 @@ public function testGetdiffWithArrayProperty(): void 'removed' => array() ); - $this->assertEquals($expectedResult, $treewalker->getdiff($struct2, $struct1, false)); + $this->assertEquals($expectedResult, $treeWalker->getdiff($struct2, $struct1, false)); } public function testGetdiffWithDifferentTypes(): void { - $treewalker = new TreeWalker(array( + $treeWalker = new TreeWalker(array( "debug" => false, "returntype" => "array" )); @@ -68,14 +68,14 @@ public function testGetdiffWithDifferentTypes(): void 'removed' => array('b/c1' => 2) ); - $this->assertEquals($expectedResult, $treewalker->getdiff($struct2, $struct1, false)); + $this->assertEquals($expectedResult, $treeWalker->getdiff($struct2, $struct1, false)); } public function testGetdiffWithJsonInput(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $result = $treewalker->getdiff('{"a":1,"b":2}', '{"a":1,"b":3}', false); + $result = $treeWalker->getdiff('{"a":1,"b":2}', '{"a":1,"b":3}', false); $this->assertArrayHasKey('edited', $result); $this->assertArrayHasKey('b', $result['edited']); @@ -85,9 +85,9 @@ public function testGetdiffWithJsonInput(): void public function testGetdiffWithObjectInput(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $result = $treewalker->getdiff((object)array('a' => 1, 'b' => 2), (object)array('a' => 1, 'b' => 3), false); + $result = $treeWalker->getdiff((object)array('a' => 1, 'b' => 2), (object)array('a' => 1, 'b' => 3), false); $this->assertArrayHasKey('edited', $result); $this->assertArrayHasKey('b', $result['edited']); @@ -95,9 +95,9 @@ public function testGetdiffWithObjectInput(): void public function testGetdiffSlashToObject(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $result = $treewalker->getdiff(array('a' => array('b' => 1)), array('a' => array('b' => 2)), true); + $result = $treeWalker->getdiff(array('a' => array('b' => 1)), array('a' => array('b' => 2)), true); $this->assertArrayHasKey('edited', $result); $this->assertArrayHasKey('a', $result['edited']); @@ -106,9 +106,9 @@ public function testGetdiffSlashToObject(): void public function testGetdiffReturnsJsonString(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "jsonstring")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "jsonstring")); - $result = $treewalker->getdiff(array('a' => 1), array('a' => 2), false); + $result = $treeWalker->getdiff(array('a' => 1), array('a' => 2), false); $this->assertIsString($result); $this->assertIsArray(json_decode($result, true)); @@ -116,9 +116,9 @@ public function testGetdiffReturnsJsonString(): void public function testGetdiffReturnsObject(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "object")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "object")); - $result = $treewalker->getdiff(array('a' => 1), array('a' => 2), false); + $result = $treeWalker->getdiff(array('a' => 1), array('a' => 2), false); $this->assertIsObject($result); $this->assertObjectHasProperty('edited', $result); @@ -130,27 +130,27 @@ public function testGetdiffReturnsObject(): void public function testGetDynamicallyValueReturnsScalar(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); $struct = array('a' => array('b' => array('c' => 42))); - $this->assertEquals(42, $treewalker->getDynamicallyValue($struct, array('a', 'b', 'c'))); + $this->assertEquals(42, $treeWalker->getDynamicallyValue($struct, array('a', 'b', 'c'))); } public function testGetDynamicallyValueReturnsNestedArray(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); $struct = array('a' => array('b' => array('x' => 1, 'y' => 2))); - $this->assertEquals(array('x' => 1, 'y' => 2), $treewalker->getDynamicallyValue($struct, array('a', 'b'))); + $this->assertEquals(array('x' => 1, 'y' => 2), $treeWalker->getDynamicallyValue($struct, array('a', 'b'))); } public function testGetDynamicallyValueWithJsonInput(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $this->assertEquals(99, $treewalker->getDynamicallyValue('{"a":{"b":99}}', array('a', 'b'))); + $this->assertEquals(99, $treeWalker->getDynamicallyValue('{"a":{"b":99}}', array('a', 'b'))); } // ------------------------------------------------------------------------- @@ -159,20 +159,20 @@ public function testGetDynamicallyValueWithJsonInput(): void public function testSetDynamicallyValueUpdatesNestedKey(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); $struct = array('a' => array('b' => 1)); - $result = $treewalker->setDynamicallyValue($struct, array('a', 'b'), 99); + $result = $treeWalker->setDynamicallyValue($struct, array('a', 'b'), 99); $this->assertEquals(array('a' => array('b' => 99)), $result); } public function testSetDynamicallyValueDoesNotMutateOriginal(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); $struct = array('a' => array('b' => 1)); - $treewalker->setDynamicallyValue($struct, array('a', 'b'), 99); + $treeWalker->setDynamicallyValue($struct, array('a', 'b'), 99); $this->assertEquals(1, $struct['a']['b']); } @@ -183,19 +183,19 @@ public function testSetDynamicallyValueDoesNotMutateOriginal(): void public function testCreateDynamicallyObjectsOnEmptyStruct(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $result = $treewalker->createDynamicallyObjects(array(), array('level1', 'level2')); + $result = $treeWalker->createDynamicallyObjects(array(), array('level1', 'level2')); $this->assertEquals(array('level1' => array('level2' => array())), $result); } public function testCreateDynamicallyObjectsAddsToExistingStruct(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); $struct = array('existing' => 1); - $result = $treewalker->createDynamicallyObjects($struct, array('new', 'path')); + $result = $treeWalker->createDynamicallyObjects($struct, array('new', 'path')); $this->assertArrayHasKey('existing', $result); $this->assertEquals(array(), $result['new']['path']); @@ -207,10 +207,10 @@ public function testCreateDynamicallyObjectsAddsToExistingStruct(): void public function testWalkerModifiesValues(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); $struct = array('a' => 1, 'b' => 2, 'c' => array('d' => 3)); - $result = $treewalker->walker($struct, function (&$struct, $key, &$value) { + $result = $treeWalker->walker($struct, function (&$struct, $key, &$value) { if (is_int($value)) { $value = $value * 2; } @@ -221,10 +221,10 @@ public function testWalkerModifiesValues(): void public function testWalkerDeletesNode(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); $struct = array('a' => 1, 'b' => 2, 'c' => 3); - $result = $treewalker->walker($struct, function (&$struct, $key, &$value) { + $result = $treeWalker->walker($struct, function (&$struct, $key, &$value) { if ($key === 'b') { unset($struct[$key]); } @@ -239,12 +239,12 @@ public function testWalkerDeletesNode(): void public function testStructMergeFirstOverridesSecond(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); $struct1 = array('a' => 1, 'b' => 2); $struct2 = array('b' => 99, 'c' => 3); - $result = $treewalker->structMerge($struct1, $struct2, false); + $result = $treeWalker->structMerge($struct1, $struct2, false); $this->assertEquals(1, $result['a']); $this->assertEquals(2, $result['b']); @@ -253,9 +253,9 @@ public function testStructMergeFirstOverridesSecond(): void public function testStructMergeSlashToObject(): void { - $treewalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); - $result = $treewalker->structMerge( + $result = $treeWalker->structMerge( array('a' => array('b' => 1)), array('a' => array('c' => 2)), true @@ -272,9 +272,9 @@ public function testStructMergeSlashToObject(): void public function testDebugModeAddsTimeKey(): void { - $treewalker = new TreeWalker(array("debug" => true, "returntype" => "array")); + $treeWalker = new TreeWalker(array("debug" => true, "returntype" => "array")); - $result = $treewalker->getdiff(array('a' => 1), array('a' => 2), false); + $result = $treeWalker->getdiff(array('a' => 1), array('a' => 2), false); $this->assertArrayHasKey('time', $result); $this->assertStringContainsString('milliseconds', $result['time']); From 90320201ba39fc0cef0ab226ea29a5cb1ebd4d06 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:18:35 -0300 Subject: [PATCH 09/19] Update README.md --- README.md | 314 +++++++++++++++++++++++++++++------------------------- 1 file changed, 170 insertions(+), 144 deletions(-) diff --git a/README.md b/README.md index 065a966..a9807ad 100644 --- a/README.md +++ b/README.md @@ -1,223 +1,249 @@ # TreeWalker -TreeWalker is a simple and small Library that will help you to work faster with manipulation of structures in PHP +A simple and lightweight PHP library for manipulating nested structures — arrays, objects and JSON strings interchangeably. [![Build Status](https://github.com/lukascivil/TreeWalker/workflows/PHP%20Composer/badge.svg)]() [![Total Downloads](https://poser.pugx.org/lukascivil/treewalker/downloads)](https://packagist.org/packages/lukascivil/treewalker) [![codecov](https://codecov.io/gh/lukascivil/TreeWalker/branch/master/graph/badge.svg)](https://codecov.io/gh/lukascivil/TreeWalker) [![License](https://poser.pugx.org/lukascivil/treewalker/license.svg)](https://packagist.org/packages/lukascivil/treewalker) -- getdiff() - Get json difference -- ~~replaceValues() - Edit json value (Recursively)~~ -- walker() - Edit json (Recursively) -- structMerge() - Joins two structures -- createDynamicallyObjects() - Create nested structure by Dynamic keys -- getDynamicallyValue() - Dynamically get a structure property -- setDynamicallyValue() - Dynamically access a structure property to set a value +## Methods -_structure = ["jsonstring", "object", "array"]_ +| Method | Description | +|--------|-------------| +| `getdiff()` | Returns the difference between two structures | +| `walker()` | Walks recursively through a structure, allowing edits and deletions | +| `structMerge()` | Merges two structures (first argument takes precedence) | +| `createDynamicallyObjects()` | Creates nested keys dynamically | +| `getDynamicallyValue()` | Reads a value by dynamic key path | +| `setDynamicallyValue()` | Sets a value by dynamic key path | -### [EXAMPLE - master](http://treewalker.lukascivil.com.br/) +### [Live example](http://treewalker.lukascivil.com.br/) -### Prerequisites +All methods accept and return any of the three supported structure types: -- PHP >= 5.5 - -## Installation +``` +"jsonstring" | "object" | "array" +``` -### Using composer +## Requirements -Put the require statement for `TreeWalker` in your `composer.json` and install: +- PHP >= 8.1 -```json -{ - "require": { - "lukascivil/treewalker": "dev-master" - } -} -``` +## Installation -``` -composer require lukascivil/treewalker dev-master +```bash +composer require lukascivil/treewalker ``` -### Manually +## Usage -include the `TreeWalker.php` +### Initialization ```php false, // true = append execution time to output + "returntype" => "array" // "jsonstring" | "object" | "array" +]); ``` -### Examples +--- -Init: +### getdiff() - $treewalker = new TreeWalker(array( - "debug"=>true, //true => return the execution time, false => not - "returntype"=>"jsonstring") //Returntype = ["obj","jsonstring","array"] - ); +Returns the difference between two structures, split into `new`, `removed` and `edited` keys. -Methods: +```php + 1, "b" => "5", "cafeina" => ["ss" => "ddd"], "oi" => 5]; +$struct2 = ["casa" => 2, "cafeina" => ["ss" => "dddd"], "oi2" => 5]; - $struct1 = array("casa"=>1, "b"=>"5", "cafeina"=>array("ss"=>"ddd"), "oi"=>5); - $struct2 = array("casa"=>2, "cafeina"=>array("ss"=>"dddd"), "oi2"=>5); +$treeWalker->getdiff($struct1, $struct2, false); // false = flat slash-delimited keys +``` - $treewalker->getdiff($struct1, $struct2, false) // false -> with slashs +Output: - Output: - { - new: { - b: "5", - oi: 5 - }, - removed: { - oi2: 5 - }, - edited: { - casa: { - oldvalue: 2, - newvalue: 1 - }, - cafeina/ss: { - oldvalue: "dddd", - newvalue: "ddd" - } +```json +{ + "new": { + "b": "5", + "oi": 5 + }, + "removed": { + "oi2": 5 + }, + "edited": { + "casa": { + "oldvalue": 2, + "newvalue": 1 }, - time: 0 + "cafeina/ss": { + "oldvalue": "dddd", + "newvalue": "ddd" + } } +} +``` +Pass `true` as the third argument to get nested output instead of slash-delimited keys: + +```php +getdiff($struct1, $struct2, true); // true = nested output ``` -```sh - //walker() - Walk recursively through the structure +--- - $struct = array("casa"=>2, "cafeina"=>array("ss"=>array("ff"=>21, "ff1"=>22)), "oi2"=>5, "1"=>"", "ss"=>"dddddf"); +### walker() - $treewalker->walker($struct, function(&$struct, $key, &$value) { - //Removing element - if ($key == "ff") { - unset($struct[$key]); - } +Walks recursively through the structure. The callback receives the parent array, the current key and the current value by reference, allowing in-place modification or deletion. - //changing element - if ($key == "ff1") { - $value = array("son" => "tiago"); - } - }) +```php + 2, "cafeina" => ["ss" => ["ff" => 21, "ff1" => 22]], "oi2" => 5]; +$treeWalker->walker($struct, function (&$struct, $key, &$value) { + if ($key === "ff") { + unset($struct[$key]); // delete node + } + + if ($key === "ff1") { + $value = ["son" => "tiago"]; // replace value + } +}); +``` + +Output: + +```json +{"casa": 2, "cafeina": {"ss": {"ff1": {"son": "tiago"}}}, "oi2": 5} ``` -```sh - //structMerge() - Merge Structures +--- - $struct1 = array("casa"=>1, "b"=>"5", "cafeina"=>array("ss1"=>"1", "ss2"=>"2"), "oi"=>5, "1" => "255"); - $struct2 = array("casa"=>2, "cafeina"=>array("ss"=>array("ff"=>21, "ff1"=>22)), "oi2"=>5, "1"=>"", "ss"=>"dddddf"); +### structMerge() - $treewalker->structMerge($struct2, $struct1, true); //true -> No slashs +Merges two structures. Values from the first argument take precedence over the second. - Output: - {"casa":2,"b":"5","cafeina":{"ss1":"1","ss2":"2","ss":{"ff":21,"ff1":22}},"oi":5,"0":"255","oi2":5,"1":"","ss":"dddddf","time":"0 miliseconds"} +```php + 1, "b" => "5", "cafeina" => ["ss1" => "1", "ss2" => "2"], "oi" => 5]; +$struct2 = ["casa" => 2, "cafeina" => ["ss" => ["ff" => 21, "ff1" => 22]], "oi2" => 5, "ss" => "dddddf"]; + +$treeWalker->structMerge($struct1, $struct2, true); // true = nested output +``` + +Output: + +```json +{"casa": 1, "b": "5", "cafeina": {"ss1": "1", "ss2": "2", "ss": {"ff": 21, "ff1": 22}}, "oi": 5, "oi2": 5, "ss": "dddddf"} ``` -```sh - //createDynamicallyObjects() - this method will create nested objects with with dynamic keys +--- - $struct = array("casa"=>1, "b"=>"5", "cafeina"=>array("ss"=>"ddd"), "oi"=>5, "1" => "255"); +### createDynamicallyObjects() - //P.s - $treewalker->createDynamicallyObjects($struct, array(1,2,5,9,10,11)); +Creates nested empty objects from a dynamic array of keys. - Output: +```php + 1, "b" => "5", "cafeina" => ["ss" => "ddd"], "oi" => 5]; + +$treeWalker->createDynamicallyObjects($struct, [1, 2, 5, 9, 10, 11]); +``` + +Output: + +```json +{ + "casa": 1, + "b": "5", + "cafeina": {"ss": "ddd"}, + "oi": 5, + "1": { + "2": { "5": { - "9": { - "10": { - "11": {} + "9": { + "10": { + "11": {} + } } - } } - } } - } + } +} ``` -```sh - //getDynamicallyValue() +--- - $struct = array("casa"=>2, "cafeina"=>array("ss"=>array("ff"=>21, "ff1"=>22)), "oi2"=>5, "1"=>"", "ss"=>"dddddf"); +### getDynamicallyValue() - Static access: - $struct["cafeina"]["ss"]; +Reads a value from a structure using a dynamic key path. - Dynamic access: - $treewalker->getDynamicallyValue($struct, array("cafeina","ss")); +```php + 2, "cafeina" => ["ss" => ["ff" => 21, "ff1" => 22]], "oi2" => 5]; + +// Static access +$struct["cafeina"]["ss"]; - Output: - {"ff":21,"ff1":22} +// Dynamic access +$treeWalker->getDynamicallyValue($struct, ["cafeina", "ss"]); ``` -```sh - //setDynamicallyValue() +Output: - $struct = array("casa"=>2, "cafeina"=>array("ss"=>array("ff"=>21, "ff1"=>22)), "oi2"=>5, "1"=>"", "ss"=>"dddddf"); +```json +{"ff": 21, "ff1": 22} +``` - Static access: - $struct["cafeina"]["ss"] = "newvalue"; +--- - Dynamic access: - $treewalker->setDynamicallyValue($struct, array("cafeina","ss"), "newvalue"); +### setDynamicallyValue() - Output: - {"casa":2,"cafeina":{"ss":"newvalue"},"oi2":5,"1":"","ss":"dddddf"} -``` +Sets a value in a structure using a dynamic key path. + +```php + 2, "cafeina" => ["ss" => ["ff" => 21, "ff1" => 22]], "oi2" => 5]; +// Static access +$struct["cafeina"]["ss"] = "newvalue"; + +// Dynamic access +$treeWalker->setDynamicallyValue($struct, ["cafeina", "ss"], "newvalue"); ``` -composer install -composer test + +Output: + +```json +{"casa": 2, "cafeina": {"ss": "newvalue"}, "oi2": 5} ``` -## Additional context -If you need the JS version to also compare objects, you can use this ([JsonDifference](https://github.com/lukascivil/jsondiffer)) lib which will have the same result on the client side. +--- -## License +## Development -The MIT License (MIT) +```bash +composer install # install dev dependencies +composer test # run tests with coverage +composer check-format # PSR-2 lint +composer format # PSR-2 autofix +``` - Copyright (c) [2016] [LUCAS CORDEIRO DA SILVA] +## Additional context - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: +If you need the JavaScript equivalent for client-side structure comparison, see [JsonDifference](https://github.com/lukascivil/jsondiffer). - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. +## License - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. +MIT © [Lucas Cordeiro da Silva](https://github.com/lukascivil) From 2f7a79f7f30ddd152aab03b3bec5c3cfd59545da Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:40:46 -0300 Subject: [PATCH 10/19] Update TreeWalkerTest.php --- tests/TreeWalkerTest.php | 89 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/tests/TreeWalkerTest.php b/tests/TreeWalkerTest.php index e9860b6..a74efc8 100644 --- a/tests/TreeWalkerTest.php +++ b/tests/TreeWalkerTest.php @@ -1,7 +1,9 @@ assertArrayHasKey('time', $result); $this->assertStringContainsString('milliseconds', $result['time']); } + + public function testDebugModeWalker(): void + { + $treeWalker = new TreeWalker(array("debug" => true, "returntype" => "array")); + + $result = $treeWalker->walker(array('a' => 1), function (&$struct, $key, &$value) {}); + + $this->assertArrayHasKey('time', $result); + $this->assertStringContainsString('milliseconds', $result['time']); + } + + public function testDebugModeStructMerge(): void + { + $treeWalker = new TreeWalker(array("debug" => true, "returntype" => "array")); + + $result = $treeWalker->structMerge(array('a' => 1), array('b' => 2), false); + + $this->assertArrayHasKey('time', $result); + $this->assertStringContainsString('milliseconds', $result['time']); + } + + // ------------------------------------------------------------------------- + // error handling and edge cases + // ------------------------------------------------------------------------- + + public function testStudyTypeReturnsFalseOnInvalidInput(): void + { + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + + $result = $treeWalker->getdiff(42, array('a' => 1), false); + + $this->assertEquals("the parameter is not a valid structure", $result); + } + + public function testInvalidReturntype(): void + { + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "invalid")); + + $result = $treeWalker->getdiff(array('a' => 1), array('a' => 2), false); + + $this->assertEquals("returntype is not valid!", $result); + } + + public function testGetDynamicallyValueKeyNotFound(): void + { + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + + $struct = array('a' => array('b' => 1)); + $result = $treeWalker->getDynamicallyValue($struct, array('a', 'nonexistent')); + + $this->assertStringContainsString('error', $result); + } + + public function testSetDynamicallyValueKeyNotFound(): void + { + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + + $struct = array('a' => array('b' => 1)); + $result = $treeWalker->setDynamicallyValue($struct, array('nonexistent', 'b'), 99); + + $this->assertEquals(array('a' => array('b' => 1)), $result); + } + + public function testGetdiffWithNonEmptyNestedObject(): void + { + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + + $obj1 = new stdClass(); + $obj1->x = 1; + $obj2 = new stdClass(); + $obj2->x = 2; + + $result = $treeWalker->getdiff(array('a' => $obj1), array('a' => $obj2), false); + + $this->assertArrayHasKey('a/x', $result['edited']); + } + + public function testGetdiffWithEmptyNestedObject(): void + { + $treeWalker = new TreeWalker(array("debug" => false, "returntype" => "array")); + + $result = $treeWalker->getdiff(array('a' => new stdClass()), array('a' => new stdClass()), false); + + $this->assertEquals(array(), $result['new']); + $this->assertEquals(array(), $result['removed']); + $this->assertEquals(array(), $result['edited']); + } } From 2258758bb0b2984f6326b7d6e5f0d4701bad86ae Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:42:48 -0300 Subject: [PATCH 11/19] Update TreeWalkerTest.php --- tests/TreeWalkerTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/TreeWalkerTest.php b/tests/TreeWalkerTest.php index a74efc8..b45c8c9 100644 --- a/tests/TreeWalkerTest.php +++ b/tests/TreeWalkerTest.php @@ -286,7 +286,8 @@ public function testDebugModeWalker(): void { $treeWalker = new TreeWalker(array("debug" => true, "returntype" => "array")); - $result = $treeWalker->walker(array('a' => 1), function (&$struct, $key, &$value) {}); + $struct = array('a' => 1); + $result = $treeWalker->walker($struct, function (&$struct, $key, &$value) {}); $this->assertArrayHasKey('time', $result); $this->assertStringContainsString('milliseconds', $result['time']); From b67c1f0ddcebf00aab4980223a37efae42cbeb02 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:45:35 -0300 Subject: [PATCH 12/19] Update php.yml --- .github/workflows/php.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index b6caadf..2291164 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -1,4 +1,4 @@ -name: PHP Composer +name: CI on: [push] From 7ea96d5e5b9b2de7d830c2e8cf828438bba66429 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:45:53 -0300 Subject: [PATCH 13/19] refactor: rename --- .github/workflows/{php.yml => ci.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{php.yml => ci.yml} (100%) diff --git a/.github/workflows/php.yml b/.github/workflows/ci.yml similarity index 100% rename from .github/workflows/php.yml rename to .github/workflows/ci.yml From 9456f2310d5acbf4eb20bd44b1ffeabe449a395b Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 03:57:12 -0300 Subject: [PATCH 14/19] chore: add release workflow --- .github/workflows/release.yml | 43 +++++++++++++++++++++++++++++++++++ .releaserc.json | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 .releaserc.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..daf1184 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,43 @@ +name: Release + +on: + workflow_run: + workflows: ["CI"] + types: [completed] + branches: [master] + +permissions: + contents: write + issues: write + pull-requests: write + +jobs: + release: + name: Semantic Release + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'success' }} + + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Semantic Release + id: release + uses: cycjimmy/semantic-release-action@v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + extra_plugins: | + @semantic-release/changelog@6 + @semantic-release/git@10 + conventional-changelog-conventionalcommits@7 + + - name: Notify Packagist + if: steps.release.outputs.new_release_published == 'true' + run: | + curl -s -XPOST \ + -H 'content-type: application/json' \ + "https://packagist.org/api/update-package?username=${{ secrets.PACKAGIST_USERNAME }}&apiToken=${{ secrets.PACKAGIST_TOKEN }}" \ + -d '{"repository":{"url":"https://github.com/${{ github.repository }}"}}' diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..f945e5c --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,42 @@ +{ + "branches": ["master"], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { "type": "feat", "release": "minor" }, + { "type": "fix", "release": "patch" }, + { "type": "perf", "release": "patch" }, + { "type": "revert", "release": "patch" }, + { "type": "docs", "release": "patch" }, + { "type": "chore", "release": "patch" }, + { "type": "refactor", "release": "minor" }, + { "type": "test", "release": "patch" }, + { "type": "ci", "release": "patch" } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits" + } + ], + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md" + } + ], + "@semantic-release/github", + [ + "@semantic-release/git", + { + "assets": ["CHANGELOG.md"], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ] + ] +} From 3c191e06190aff88357a935f78b90d22d548e45a Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 04:23:40 -0300 Subject: [PATCH 15/19] Create SKILL.md --- .claude/skills/create-or-update-pr/SKILL.md | 67 +++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .claude/skills/create-or-update-pr/SKILL.md diff --git a/.claude/skills/create-or-update-pr/SKILL.md b/.claude/skills/create-or-update-pr/SKILL.md new file mode 100644 index 0000000..5f9c68a --- /dev/null +++ b/.claude/skills/create-or-update-pr/SKILL.md @@ -0,0 +1,67 @@ +--- +name: create-or-update-pr +description: Creates or updates the GitHub Pull Request for the current branch, generating title and body from git log and diff. +--- + +Your task is to create or update the GitHub Pull Request for the current branch. + +## Steps + +1. Run these commands in parallel to gather context: + - `git log --oneline $(git merge-base HEAD master)..HEAD` — commits on this branch + - `git diff $(git merge-base HEAD master)..HEAD --stat` — changed files summary + - `gh pr view --json number,title,body,state 2>/dev/null` — existing PR, if any + +2. Analyze all commits and changed files to understand the intent of the branch. + +3. Build the PR title: + - Follow conventional commits: `type(scope): short description` + - Use the most significant type across all commits (`feat` > `fix` > `refactor` > `chore`) + - If there is only one commit and its message is already a good title, use it directly + - Keep it under 72 characters + - Do not add a period at the end + +4. Build the PR body using this template: + +``` +## Summary +- +- + +## Changes +- : + +## Test plan +- [ ] +``` + +- Summary: 2–4 bullets on _what_ and _why_, not _how_ +- Changes: one line per meaningful file group or area changed +- Test plan: concrete steps a reviewer can follow to verify the PR + +5. If no PR exists for this branch, create one targeting `master`: + +```bash +gh pr create --title "..." --body "$(cat <<'EOF' +... +EOF +)" +``` + +6. If a PR already exists, update its title and body: + +```bash +gh pr edit --title "..." --body "$(cat <<'EOF' +... +EOF +)" +``` + +7. Output the PR URL at the end. + +## Rules + +- Never push commits — only create or edit the PR metadata +- If the branch has no commits ahead of master, tell the user and stop +- Use the `gh` CLI for all GitHub operations +- Always use a HEREDOC (`<<'EOF'`) to pass the body so newlines are preserved From efe83720ea90b62cf8ae2caaed8b231da95414a5 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 04:35:28 -0300 Subject: [PATCH 16/19] chore: update packahges --- .github/workflows/ci.yml | 3 + .gitignore | 1 + .php-cs-fixer.dist.php | 10 + composer.json | 13 +- composer.lock | 4215 +++++++++++++++++++++++++++++++------- 5 files changed, 3462 insertions(+), 780 deletions(-) create mode 100644 .php-cs-fixer.dist.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2291164..b594887 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,9 @@ jobs: - name: Install dependencies run: composer install --prefer-dist --no-progress + - name: Check code style + run: composer run-script check-format + - name: Run test suite run: composer run-script test diff --git a/.gitignore b/.gitignore index 1af099c..e2d7689 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .idea /vendor coverage.xml +.claude/settings.local.json diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..813a1c9 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,10 @@ +in([__DIR__ . '/src', __DIR__ . '/tests']); + +return (new PhpCsFixer\Config()) + ->setRules([ + '@PSR12' => true, + ]) + ->setFinder($finder); diff --git a/composer.json b/composer.json index 5116ff4..fb08b4b 100644 --- a/composer.json +++ b/composer.json @@ -29,11 +29,18 @@ }, "scripts": { "test": "vendor/bin/phpunit --coverage-text", - "check-format": "vendor/bin/phpcs --standard=PSR2 src", - "format": "vendor/bin/phpcbf --standard=PSR2 src && vendor/bin/phpcbf --standard=PSR2 tests" + "check-format": [ + "vendor/bin/php-cs-fixer check --diff", + "vendor/bin/phpcs --standard=PSR2 src tests" + ], + "format": [ + "vendor/bin/php-cs-fixer fix", + "vendor/bin/phpcbf --standard=PSR2 src tests" + ] }, "require-dev": { "phpunit/phpunit": "^10", - "squizlabs/php_codesniffer": "3.*" + "friendsofphp/php-cs-fixer": "^3.95", + "squizlabs/php_codesniffer": "^4.0" } } diff --git a/composer.lock b/composer.lock index 56158d6..35c416d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,285 +4,2659 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1997e5fc03e3fc4a199c245852aac78f", + "content-hash": "389fdcfbd8bbdc9653fa76860f45cbca", "packages": [], "packages-dev": [ { - "name": "myclabs/deep-copy", - "version": "1.13.4", + "name": "clue/ndjson-react", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", - "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3 <3.2.2" + "php": ">=5.3", + "react/stream": "^1.2" }, "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpspec/prophecy": "^1.10", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" }, "type": "library", "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], "psr-4": { - "DeepCopy\\": "src/DeepCopy/" + "Clue\\React\\NDJson\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" ], "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" }, "funding": [ { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" } ], - "time": "2025-08-01T08:46:24+00:00" + "time": "2022-12-23T10:58:28+00:00" }, { - "name": "nikic/php-parser", - "version": "v5.7.0", + "name": "composer/pcre", + "version": "3.3.2", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" }, "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^9.0" + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" }, - "bin": [ - "bin/php-parse" - ], "type": "library", "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, "branch-alias": { - "dev-master": "5.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { "psr-4": { - "PhpParser\\": "lib/PhpParser" + "Composer\\Pcre\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" } ], - "description": "A PHP parser written in PHP", + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", "keywords": [ - "parser", - "php" + "PCRE", + "preg", + "regex", + "regular expression" ], "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" }, - "time": "2025-12-06T11:56:16+00:00" + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" }, { - "name": "phar-io/manifest", - "version": "2.0.4", + "name": "composer/semver", + "version": "3.4.4", "source": { "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "54750ef60c58e43759730615a392c31c80e23176" + "url": "https://github.com/composer/semver.git", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", - "reference": "54750ef60c58e43759730615a392c31c80e23176", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Composer\\Semver\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" }, { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.4" + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.4" }, "funding": [ { - "url": "https://github.com/theseer", + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", "type": "github" } ], - "time": "2024-03-03T12:33:53+00:00" + "time": "2025-08-20T19:15:30+00:00" }, { - "name": "phar-io/version", - "version": "3.2.1", + "name": "composer/xdebug-handler", + "version": "3.0.5", "source": { "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" }, { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "url": "https://github.com/composer", + "type": "github" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" } ], - "description": "Library for handling version information and constraints", + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "ergebnis/agent-detector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/ergebnis/agent-detector.git", + "reference": "5b654a9f1ff8a5d2ce6a57568df5ae8801c87f64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ergebnis/agent-detector/zipball/5b654a9f1ff8a5d2ce6a57568df5ae8801c87f64", + "reference": "5b654a9f1ff8a5d2ce6a57568df5ae8801c87f64", + "shasum": "" + }, + "require": { + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.50.0", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.60.2", + "ergebnis/phpstan-rules": "^2.13.1", + "ergebnis/phpunit-slow-test-detector": "^2.24.0", + "ergebnis/rector-rules": "^1.16.0", + "fakerphp/faker": "^1.24.1", + "infection/infection": "^0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.46", + "phpstan/phpstan-deprecation-rules": "^2.0.4", + "phpstan/phpstan-phpunit": "^2.0.16", + "phpstan/phpstan-strict-rules": "^2.0.10", + "phpunit/phpunit": "^9.6.34", + "rector/rector": "^2.4.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.0-dev" + }, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" + } + }, + "autoload": { + "psr-4": { + "Ergebnis\\AgentDetector\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" + } + ], + "description": "Provides a detector for detecting the presence of an agent.", + "homepage": "https://github.com/ergebnis/agent-detector", "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" + "issues": "https://github.com/ergebnis/agent-detector/issues", + "security": "https://github.com/ergebnis/agent-detector/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/agent-detector" }, - "time": "2022-02-21T01:04:05+00:00" + "time": "2026-04-10T13:45:13+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "10.1.16", + "name": "evenement/evenement", + "version": "v3.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.19.1 || ^5.1.0", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-text-template": "^3.0.1", - "sebastian/code-unit-reverse-lookup": "^3.0.0", - "sebastian/complexity": "^3.2.0", - "sebastian/environment": "^6.1.0", - "sebastian/lines-of-code": "^2.0.2", - "sebastian/version": "^4.0.1", - "theseer/tokenizer": "^1.2.3" + "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "^10.1" + "phpunit/phpunit": "^9 || ^6" }, - "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", + "autoload": { + "psr-4": { + "Evenement\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2025-08-14T07:29:31+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.95.1", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "a9727678fbd12997f1d9de8f4a37824ed9df1065" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a9727678fbd12997f1d9de8f4a37824ed9df1065", + "reference": "a9727678fbd12997f1d9de8f4a37824ed9df1065", + "shasum": "" + }, + "require": { + "clue/ndjson-react": "^1.3", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.5", + "ergebnis/agent-detector": "^1.1.1", + "ext-filter": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.3", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.6", + "react/event-loop": "^1.5", + "react/socket": "^1.16", + "react/stream": "^1.4", + "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0 || ^8.0", + "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.33", + "symfony/polyfill-php80": "^1.33", + "symfony/polyfill-php81": "^1.33", + "symfony/polyfill-php84": "^1.33", + "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2 || ^8.0", + "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3.1 || ^2.8.0", + "infection/infection": "^0.32.6", + "justinrainbow/json-schema": "^6.8.0", + "keradus/cli-executor": "^2.3", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.9.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.8", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.8", + "phpunit/phpunit": "^9.6.34 || ^10.5.63 || ^11.5.55", + "symfony/polyfill-php85": "^1.33", + "symfony/var-dumper": "^5.4.48 || ^6.4.32 || ^7.4.4 || ^8.0.8", + "symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0.8" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/**/Internal/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.95.1" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2026-04-12T17:00:09+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.7.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + }, + "time": "2025-12-06T11:56:16+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.16", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:31:57+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.5.63", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "33198268dad71e926626b618f3ec3966661e4d90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33198268dad71e926626b618f3ec3966661e4d90", + "reference": "33198268dad71e926626b618f3ec3966661e4d90", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.5", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.4", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.1", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.63" + }, + "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-01-27T05:48:37+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.7", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/970f0e71945556422ee4570ccbabaedc3cf04ad3", + "reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.7" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-12-23T15:25:20+00:00" + }, + { + "name": "react/dns", + "version": "v1.14.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/7562c05391f42701c1fccf189c8225fece1cd7c3", + "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.14.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-11-18T19:34:28+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/ba276bda6083df7e0050fd9b33f66ad7a4ac747a", + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.6.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-11-17T20:46:25+00:00" + }, + { + "name": "react/promise", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.12.28 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-08-19T18:57:03+00:00" + }, + { + "name": "react/socket", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/ef5b17b81f6f60504c539313f94f2d826c5faa08", + "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.17.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-11-19T20:47:34+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:12:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.5" + }, + "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:25:16+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68ff824baeae169ec9f2137158ee529584553799" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:37:17+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:15:17+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-23T08:47:14+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "0735b90f4da94969541dac1da743446e276defa6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0735b90f4da94969541dac1da743446e276defa6", + "reference": "0735b90f4da94969541dac1da743446e276defa6", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:09:11+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:19:19+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:38:20+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1.x-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -297,21 +2671,14 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" }, "funding": [ { @@ -319,32 +2686,32 @@ "type": "github" } ], - "time": "2024-08-22T04:31:57+00:00" + "time": "2023-02-03T07:06:18+00:00" }, { - "name": "phpunit/php-file-iterator", - "version": "4.1.0", + "name": "sebastian/recursion-context", + "version": "5.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/47e34210757a2f37a97dcd207d032e1b01e64c7a", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a", "shasum": "" }, "require": { "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -359,53 +2726,64 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + "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/5.0.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" } ], - "time": "2023-08-31T06:24:48+00:00" + "time": "2025-08-10T07:50:56+00:00" }, { - "name": "phpunit/php-invoker", + "name": "sebastian/type", "version": "4.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { "php": ">=8.1" }, "require-dev": { - "ext-pcntl": "*", "phpunit/phpunit": "^10.0" }, - "suggest": { - "ext-pcntl": "*" - }, "type": "library", "extra": { "branch-alias": { @@ -428,14 +2806,11 @@ "role": "lead" } ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" }, "funding": [ { @@ -443,32 +2818,29 @@ "type": "github" } ], - "time": "2023-02-03T06:56:09+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { - "name": "phpunit/php-text-template", - "version": "3.0.1", + "name": "sebastian/version", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { "php": ">=8.1" }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -487,15 +2859,11 @@ "role": "lead" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" }, "funding": [ { @@ -503,1207 +2871,1500 @@ "type": "github" } ], - "time": "2023-08-31T14:07:24+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { - "name": "phpunit/php-timer", - "version": "6.0.0", + "name": "squizlabs/php_codesniffer", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "0525c73950de35ded110cffafb9892946d7771b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0525c73950de35ded110cffafb9892946d7771b5", + "reference": "0525c73950de35ded110cffafb9892946d7771b5", "shasum": "" }, "require": { - "php": ">=8.1" + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=7.2.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^8.4.0 || ^9.3.4 || ^10.5.32 || 11.3.3 - 11.5.28 || ^11.5.31" }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Greg Sherwood", + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ - "timer" + "phpcs", + "standards", + "static analysis" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2023-02-03T06:57:52+00:00" + "time": "2025-11-10T16:43:36+00:00" }, { - "name": "phpunit/phpunit", - "version": "10.5.63", + "name": "symfony/console", + "version": "v8.0.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "33198268dad71e926626b618f3ec3966661e4d90" + "url": "https://github.com/symfony/console.git", + "reference": "5b66d385dc58f69652e56f78a4184615e3f2b7f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33198268dad71e926626b618f3ec3966661e4d90", - "reference": "33198268dad71e926626b618f3ec3966661e4d90", + "url": "https://api.github.com/repos/symfony/console/zipball/5b66d385dc58f69652e56f78a4184615e3f2b7f7", + "reference": "5b66d385dc58f69652e56f78a4184615e3f2b7f7", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.4", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.16", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-invoker": "^4.0.0", - "phpunit/php-text-template": "^3.0.1", - "phpunit/php-timer": "^6.0.0", - "sebastian/cli-parser": "^2.0.1", - "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.5", - "sebastian/diff": "^5.1.1", - "sebastian/environment": "^6.1.0", - "sebastian/exporter": "^5.1.4", - "sebastian/global-state": "^6.0.2", - "sebastian/object-enumerator": "^5.0.0", - "sebastian/recursion-context": "^5.0.1", - "sebastian/type": "^4.0.0", - "sebastian/version": "^4.0.1" + "php": ">=8.4", + "symfony/polyfill-mbstring": "^1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.4|^8.0" }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "10.5-dev" - } + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/event-dispatcher": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/lock": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/stopwatch": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0" }, + "type": "library", "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", "keywords": [ - "phpunit", - "testing", - "xunit" + "cli", + "command-line", + "console", + "terminal" ], "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.63" + "source": "https://github.com/symfony/console/tree/v8.0.8" }, "funding": [ { - "url": "https://phpunit.de/sponsors.html", + "url": "https://symfony.com/sponsor", "type": "custom" }, { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/fabpot", "type": "github" }, { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2026-01-27T05:48:37+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { - "name": "sebastian/cli-parser", - "version": "2.0.1", + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { "php": ">=8.1" }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "3.6-dev" } }, "autoload": { - "classmap": [ - "src/" + "files": [ + "function.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-03-02T07:12:49+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { - "name": "sebastian/code-unit", - "version": "2.0.0", + "name": "symfony/event-dispatcher", + "version": "v8.0.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "f662acc6ab22a3d6d716dcb44c381c6002940df6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f662acc6ab22a3d6d716dcb44c381c6002940df6", + "reference": "f662acc6ab22a3d6d716dcb44c381c6002940df6", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.4", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/security-http": "<7.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "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", - "extra": { - "branch-alias": { - "dev-main": "2.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.8" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-03T06:58:43+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", + "name": "symfony/event-dispatcher-contracts", + "version": "v3.6.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", "shasum": "" }, "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" + "php": ">=8.1", + "psr/event-dispatcher": "^1" }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.6-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-03T06:59:15+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { - "name": "sebastian/comparator", - "version": "5.0.5", + "name": "symfony/filesystem", + "version": "v8.0.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d" + "url": "https://github.com/symfony/filesystem.git", + "reference": "66b769ae743ce2d13e435528fbef4af03d623e5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55dfef806eb7dfeb6e7a6935601fef866f8ca48d", - "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/66b769ae743ce2d13e435528fbef4af03d623e5a", + "reference": "66b769ae743ce2d13e435528fbef4af03d623e5a", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" + "php": ">=8.4", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "phpunit/phpunit": "^10.5" + "symfony/process": "^7.4|^8.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v8.0.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "name": "Volker Dusch", - "email": "github@wallbash.com" + "url": "https://github.com/fabpot", + "type": "github" }, { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" + "time": "2026-03-30T15:14:47+00:00" + }, + { + "name": "symfony/finder", + "version": "v8.0.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "8da41214757b87d97f181e3d14a4179286151007" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/8da41214757b87d97f181e3d14a4179286151007", + "reference": "8da41214757b87d97f181e3d14a4179286151007", + "shasum": "" + }, + "require": { + "php": ">=8.4" + }, + "require-dev": { + "symfony/filesystem": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.5" + "source": "https://github.com/symfony/finder/tree/v8.0.8" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" + "url": "https://github.com/fabpot", + "type": "github" }, { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2026-01-24T09:25:16+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { - "name": "sebastian/complexity", - "version": "3.2.0", + "name": "symfony/options-resolver", + "version": "v8.0.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "b48bce0a70b914f6953dafbd10474df232ed4de8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b48bce0a70b914f6953dafbd10474df232ed4de8", + "reference": "b48bce0a70b914f6953dafbd10474df232ed4de8", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" + "php": ">=8.4", + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.2-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + "source": "https://github.com/symfony/options-resolver/tree/v8.0.8" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-12-21T08:37:17+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { - "name": "sebastian/diff", - "version": "5.1.1", + "name": "symfony/polyfill-ctype", + "version": "v1.36.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.2" }, - "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^6.4" + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "5.1-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" }, { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" + "compatibility", + "ctype", + "polyfill", + "portable" ], "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.36.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-03-02T07:15:17+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { - "name": "sebastian/environment", - "version": "6.1.0", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.36.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "ad1b7b9092976d6c948b8a187cec9faaea9ec1df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/ad1b7b9092976d6c948b8a187cec9faaea9ec1df", + "reference": "ad1b7b9092976d6c948b8a187cec9faaea9ec1df", "shasum": "" }, "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" + "php": ">=7.2" }, "suggest": { - "ext-posix": "*" + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "6.1-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "https://github.com/sebastianbergmann/environment", + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", "keywords": [ - "Xdebug", - "environment", - "hhvm" + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" ], "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.36.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-03-23T08:47:14+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { - "name": "sebastian/exporter", - "version": "5.1.4", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.36.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "0735b90f4da94969541dac1da743446e276defa6" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0735b90f4da94969541dac1da743446e276defa6", - "reference": "0735b90f4da94969541dac1da743446e276defa6", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" + "php": ">=7.2" }, - "require-dev": { - "phpunit/phpunit": "^10.5" + "suggest": { + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "5.1-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", "keywords": [ - "export", - "exporter" + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" ], "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.4" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.36.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" + "url": "https://github.com/fabpot", + "type": "github" }, { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-09-24T06:09:11+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/global-state", - "version": "6.0.2", + "name": "symfony/polyfill-mbstring", + "version": "v1.36.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "ext-iconv": "*", + "php": ">=7.2" }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^10.0" + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "6.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Snapshotting of global state", - "homepage": "https://www.github.com/sebastianbergmann/global-state", + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", "keywords": [ - "global state" + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" ], "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.36.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-03-02T07:19:19+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { - "name": "sebastian/lines-of-code", - "version": "2.0.2", + "name": "symfony/polyfill-php80", + "version": "v1.36.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "2.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.36.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-12-21T08:38:20+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "5.0.0", + "name": "symfony/polyfill-php81", + "version": "v1.36.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "5.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.36.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-03T07:08:32+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/object-reflector", - "version": "3.0.0", + "name": "symfony/polyfill-php84", + "version": "v1.36.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", "shasum": "" }, "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.36.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-03T07:06:18+00:00" + "time": "2026-04-10T18:47:49+00:00" }, { - "name": "sebastian/recursion-context", - "version": "5.0.1", + "name": "symfony/process", + "version": "v8.0.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a" + "url": "https://github.com/symfony/process.git", + "reference": "cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/47e34210757a2f37a97dcd207d032e1b01e64c7a", - "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a", + "url": "https://api.github.com/repos/symfony/process/zipball/cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc", + "reference": "cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc", "shasum": "" }, "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.5" + "php": ">=8.4" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.1" + "source": "https://github.com/symfony/process/tree/v8.0.8" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" + "url": "https://github.com/fabpot", + "type": "github" }, { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-08-10T07:50:56+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { - "name": "sebastian/type", - "version": "4.0.0", + "name": "symfony/service-contracts", + "version": "v3.6.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, - "require-dev": { - "phpunit/phpunit": "^10.0" + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "3.6-dev" } }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-03T07:10:45+00:00" + "time": "2025-07-15T11:30:57+00:00" }, { - "name": "sebastian/version", - "version": "4.0.1", + "name": "symfony/stopwatch", + "version": "v8.0.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + "url": "https://github.com/symfony/stopwatch.git", + "reference": "85954ed72d5440ea4dc9a10b7e49e01df766ffa3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/85954ed72d5440ea4dc9a10b7e49e01df766ffa3", + "reference": "85954ed72d5440ea4dc9a10b7e49e01df766ffa3", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.4", + "symfony/service-contracts": "^2.5|^3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + "source": "https://github.com/symfony/stopwatch/tree/v8.0.8" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-07T11:34:05+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { - "name": "squizlabs/php_codesniffer", - "version": "3.13.5", + "name": "symfony/string", + "version": "v8.0.8", "source": { "type": "git", - "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4" + "url": "https://github.com/symfony/string.git", + "reference": "ae9488f874d7603f9d2dfbf120203882b645d963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0ca86845ce43291e8f5692c7356fccf3bcf02bf4", - "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4", + "url": "https://api.github.com/repos/symfony/string/zipball/ae9488f874d7603f9d2dfbf120203882b645d963", + "reference": "ae9488f874d7603f9d2dfbf120203882b645d963", "shasum": "" }, "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" + "php": ">=8.4", + "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": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" + "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" }, - "bin": [ - "bin/phpcbf", - "bin/phpcs" - ], "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Greg Sherwood", - "role": "Former lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "Current lead" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "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": [ - "phpcs", - "standards", - "static analysis" + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" ], "support": { - "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", - "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", - "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + "source": "https://github.com/symfony/string/tree/v8.0.8" }, "funding": [ { - "url": "https://github.com/PHPCSStandards", - "type": "github" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "url": "https://github.com/jrfnl", + "url": "https://github.com/fabpot", "type": "github" }, { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://thanks.dev/u/gh/phpcsstandards", - "type": "thanks_dev" + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2025-11-04T16:30:35+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "theseer/tokenizer", From b3c5655ff8cf5e84ed513aabc053557eac45b45b Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 04:38:45 -0300 Subject: [PATCH 17/19] chore: adjust dependencies --- composer.json | 5 ++ composer.lock | 183 ++++++++++++++++++++++++++------------------------ 2 files changed, 101 insertions(+), 87 deletions(-) diff --git a/composer.json b/composer.json index fb08b4b..0a1a84d 100644 --- a/composer.json +++ b/composer.json @@ -42,5 +42,10 @@ "phpunit/phpunit": "^10", "friendsofphp/php-cs-fixer": "^3.95", "squizlabs/php_codesniffer": "^4.0" + }, + "config": { + "platform": { + "php": "8.1" + } } } diff --git a/composer.lock b/composer.lock index 35c416d..d780fcd 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": "389fdcfbd8bbdc9653fa76860f45cbca", + "content-hash": "3f64b490c84863b76d51782c0cbe4ae8", "packages": [], "packages-dev": [ { @@ -2954,39 +2954,47 @@ }, { "name": "symfony/console", - "version": "v8.0.8", + "version": "v6.4.36", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "5b66d385dc58f69652e56f78a4184615e3f2b7f7" + "reference": "9f481cfb580db8bcecc9b2d4c63f3e13df022ad5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/5b66d385dc58f69652e56f78a4184615e3f2b7f7", - "reference": "5b66d385dc58f69652e56f78a4184615e3f2b7f7", + "url": "https://api.github.com/repos/symfony/console/zipball/9f481cfb580db8bcecc9b2d4c63f3e13df022ad5", + "reference": "9f481cfb580db8bcecc9b2d4c63f3e13df022ad5", "shasum": "" }, "require": { - "php": ">=8.4", - "symfony/polyfill-mbstring": "^1.0", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^7.4|^8.0" + "symfony/string": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" }, "provide": { "psr/log-implementation": "1.0|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/event-dispatcher": "^7.4|^8.0", - "symfony/http-foundation": "^7.4|^8.0", - "symfony/http-kernel": "^7.4|^8.0", - "symfony/lock": "^7.4|^8.0", - "symfony/messenger": "^7.4|^8.0", - "symfony/process": "^7.4|^8.0", - "symfony/stopwatch": "^7.4|^8.0", - "symfony/var-dumper": "^7.4|^8.0" + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -3020,7 +3028,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v8.0.8" + "source": "https://github.com/symfony/console/tree/v6.4.36" }, "funding": [ { @@ -3040,7 +3048,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-03-27T15:30:51+00:00" }, { "name": "symfony/deprecation-contracts", @@ -3111,24 +3119,24 @@ }, { "name": "symfony/event-dispatcher", - "version": "v8.0.8", + "version": "v6.4.36", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "f662acc6ab22a3d6d716dcb44c381c6002940df6" + "reference": "fc828863e26ceec86e2513b5e46aa0b149d76b69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f662acc6ab22a3d6d716dcb44c381c6002940df6", - "reference": "f662acc6ab22a3d6d716dcb44c381c6002940df6", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/fc828863e26ceec86e2513b5e46aa0b149d76b69", + "reference": "fc828863e26ceec86e2513b5e46aa0b149d76b69", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.1", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/security-http": "<7.4", + "symfony/dependency-injection": "<5.4", "symfony/service-contracts": "<2.5" }, "provide": { @@ -3137,14 +3145,13 @@ }, "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/config": "^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/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^7.4|^8.0" + "symfony/stopwatch": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -3172,7 +3179,7 @@ "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/event-dispatcher/tree/v8.0.8" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.36" }, "funding": [ { @@ -3192,7 +3199,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-03-30T11:18:01+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -3272,25 +3279,25 @@ }, { "name": "symfony/filesystem", - "version": "v8.0.8", + "version": "v6.4.34", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "66b769ae743ce2d13e435528fbef4af03d623e5a" + "reference": "01ffe0411b842f93c571e5c391f289c3fdd498c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/66b769ae743ce2d13e435528fbef4af03d623e5a", - "reference": "66b769ae743ce2d13e435528fbef4af03d623e5a", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/01ffe0411b842f93c571e5c391f289c3fdd498c3", + "reference": "01ffe0411b842f93c571e5c391f289c3fdd498c3", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^7.4|^8.0" + "symfony/process": "^5.4|^6.4|^7.0" }, "type": "library", "autoload": { @@ -3318,7 +3325,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v8.0.8" + "source": "https://github.com/symfony/filesystem/tree/v6.4.34" }, "funding": [ { @@ -3338,27 +3345,27 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-02-24T17:51:06+00:00" }, { "name": "symfony/finder", - "version": "v8.0.8", + "version": "v6.4.34", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "8da41214757b87d97f181e3d14a4179286151007" + "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/8da41214757b87d97f181e3d14a4179286151007", - "reference": "8da41214757b87d97f181e3d14a4179286151007", + "url": "https://api.github.com/repos/symfony/finder/zipball/9590e86be1d1c57bfbb16d0dd040345378c20896", + "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.1" }, "require-dev": { - "symfony/filesystem": "^7.4|^8.0" + "symfony/filesystem": "^6.0|^7.0" }, "type": "library", "autoload": { @@ -3386,7 +3393,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v8.0.8" + "source": "https://github.com/symfony/finder/tree/v6.4.34" }, "funding": [ { @@ -3406,24 +3413,24 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-01-28T15:16:37+00:00" }, { "name": "symfony/options-resolver", - "version": "v8.0.8", + "version": "v6.4.30", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "b48bce0a70b914f6953dafbd10474df232ed4de8" + "reference": "eeaa8cabe54c7b3516938c72a4a161c0cc80a34f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b48bce0a70b914f6953dafbd10474df232ed4de8", - "reference": "b48bce0a70b914f6953dafbd10474df232ed4de8", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/eeaa8cabe54c7b3516938c72a4a161c0cc80a34f", + "reference": "eeaa8cabe54c7b3516938c72a4a161c0cc80a34f", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.1", "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", @@ -3457,7 +3464,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v8.0.8" + "source": "https://github.com/symfony/options-resolver/tree/v6.4.30" }, "funding": [ { @@ -3477,7 +3484,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2025-11-12T13:06:53+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4060,20 +4067,20 @@ }, { "name": "symfony/process", - "version": "v8.0.8", + "version": "v6.4.33", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc" + "reference": "c46e854e79b52d07666e43924a20cb6dc546644e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc", - "reference": "cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc", + "url": "https://api.github.com/repos/symfony/process/zipball/c46e854e79b52d07666e43924a20cb6dc546644e", + "reference": "c46e854e79b52d07666e43924a20cb6dc546644e", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.1" }, "type": "library", "autoload": { @@ -4101,7 +4108,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v8.0.8" + "source": "https://github.com/symfony/process/tree/v6.4.33" }, "funding": [ { @@ -4121,7 +4128,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-01-23T16:02:12+00:00" }, { "name": "symfony/service-contracts", @@ -4212,20 +4219,20 @@ }, { "name": "symfony/stopwatch", - "version": "v8.0.8", + "version": "v6.4.24", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "85954ed72d5440ea4dc9a10b7e49e01df766ffa3" + "reference": "b67e94e06a05d9572c2fa354483b3e13e3cb1898" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/85954ed72d5440ea4dc9a10b7e49e01df766ffa3", - "reference": "85954ed72d5440ea4dc9a10b7e49e01df766ffa3", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b67e94e06a05d9572c2fa354483b3e13e3cb1898", + "reference": "b67e94e06a05d9572c2fa354483b3e13e3cb1898", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.1", "symfony/service-contracts": "^2.5|^3" }, "type": "library", @@ -4254,7 +4261,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v8.0.8" + "source": "https://github.com/symfony/stopwatch/tree/v6.4.24" }, "funding": [ { @@ -4274,38 +4281,37 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2025-07-10T08:14:14+00:00" }, { "name": "symfony/string", - "version": "v8.0.8", + "version": "v6.4.34", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ae9488f874d7603f9d2dfbf120203882b645d963" + "reference": "2adaf4106f2ef4c67271971bde6d3fe0a6936432" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ae9488f874d7603f9d2dfbf120203882b645d963", - "reference": "ae9488f874d7603f9d2dfbf120203882b645d963", + "url": "https://api.github.com/repos/symfony/string/zipball/2adaf4106f2ef4c67271971bde6d3fe0a6936432", + "reference": "2adaf4106f2ef4c67271971bde6d3fe0a6936432", "shasum": "" }, "require": { - "php": ">=8.4", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-intl-grapheme": "^1.33", - "symfony/polyfill-intl-normalizer": "^1.0", - "symfony/polyfill-mbstring": "^1.0" + "php": ">=8.1", + "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.4|^8.0", - "symfony/http-client": "^7.4|^8.0", - "symfony/intl": "^7.4|^8.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^7.4|^8.0" + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -4344,7 +4350,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v8.0.8" + "source": "https://github.com/symfony/string/tree/v6.4.34" }, "funding": [ { @@ -4364,7 +4370,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-02-08T20:44:54+00:00" }, { "name": "theseer/tokenizer", @@ -4426,5 +4432,8 @@ "php": ">=8.1" }, "platform-dev": {}, + "platform-overrides": { + "php": "8.1" + }, "plugin-api-version": "2.9.0" } From 538819577cc07d1b3ff9cdc620300f1d207adf46 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 04:41:00 -0300 Subject: [PATCH 18/19] style: adjust code --- .gitignore | 1 + tests/TreeWalkerTest.php | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e2d7689..b6183ac 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /vendor coverage.xml .claude/settings.local.json +.php-cs-fixer.cache diff --git a/tests/TreeWalkerTest.php b/tests/TreeWalkerTest.php index b45c8c9..3e6d811 100644 --- a/tests/TreeWalkerTest.php +++ b/tests/TreeWalkerTest.php @@ -287,7 +287,8 @@ public function testDebugModeWalker(): void $treeWalker = new TreeWalker(array("debug" => true, "returntype" => "array")); $struct = array('a' => 1); - $result = $treeWalker->walker($struct, function (&$struct, $key, &$value) {}); + $result = $treeWalker->walker($struct, function (&$struct, $key, &$value) { + }); $this->assertArrayHasKey('time', $result); $this->assertStringContainsString('milliseconds', $result['time']); From 7e0f777c27b723c58bfe5ca51f47cb9f96acaaf1 Mon Sep 17 00:00:00 2001 From: lukascivil Date: Sat, 25 Apr 2026 04:43:27 -0300 Subject: [PATCH 19/19] Update composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 0a1a84d..14d68a8 100644 --- a/composer.json +++ b/composer.json @@ -31,11 +31,11 @@ "test": "vendor/bin/phpunit --coverage-text", "check-format": [ "vendor/bin/php-cs-fixer check --diff", - "vendor/bin/phpcs --standard=PSR2 src tests" + "vendor/bin/phpcs --standard=PSR2 --exclude=PSR1.Classes.ClassDeclaration src tests" ], "format": [ "vendor/bin/php-cs-fixer fix", - "vendor/bin/phpcbf --standard=PSR2 src tests" + "vendor/bin/phpcbf --standard=PSR2 --exclude=PSR1.Classes.ClassDeclaration src tests" ] }, "require-dev": {