From 9bb05a2e59f0d18c0adf3834ac0d2fffab102edd Mon Sep 17 00:00:00 2001 From: Pratiksha Date: Fri, 10 Jan 2025 16:00:08 +0530 Subject: [PATCH 1/9] wip --- src/Neo4jQueryAPI.php | 87 ++- src/Objects/QueryArguments.php | 74 +-- .../Neo4jQueryAPIIntegrationTest.php | 28 +- .../expected/complex-query-profile.php | 72 +++ .../responses/complex-query-profile.json | 527 ++++++++++++++++++ 5 files changed, 688 insertions(+), 100 deletions(-) create mode 100644 tests/resources/expected/complex-query-profile.php create mode 100644 tests/resources/responses/complex-query-profile.json diff --git a/src/Neo4jQueryAPI.php b/src/Neo4jQueryAPI.php index 53a97cbe..87b83e20 100644 --- a/src/Neo4jQueryAPI.php +++ b/src/Neo4jQueryAPI.php @@ -51,23 +51,19 @@ public static function login(string $address, string $username, string $password public function run(string $cypher, array $parameters = [], string $database = 'neo4j'): ResultSet { try { - // Prepare the payload for the request $payload = [ 'statement' => $cypher, 'parameters' => empty($parameters) ? new stdClass() : $parameters, 'includeCounters' => true ]; - // Execute the request to the Neo4j server $response = $this->client->post('/db/' . $database . '/query/v2', [ 'json' => $payload, ]); - // Decode the response body $data = json_decode($response->getBody()->getContents(), true); $ogm = new OGM(); - // Extract result rows $keys = $data['data']['fields']; $values = $data['data']['values']; $rows = array_map(function ($resultRow) use ($ogm, $keys) { @@ -79,30 +75,25 @@ public function run(string $cypher, array $parameters = [], string $database = ' return new ResultRow($data); }, $values); + $profile = isset($data['profiledQueryPlan']) ? $this->createProfileData($data['profiledQueryPlan']) : null; - if (isset($data['profiledQueryPlan'])) { - $profile = $this->createProfileData($data['profiledQueryPlan']); - } - - - // Return a ResultSet containing rows, counters, and the profiled query plan return new ResultSet( $rows, new ResultCounters( - containsUpdates: $data['counters']['containsUpdates'], - nodesCreated: $data['counters']['nodesCreated'], - nodesDeleted: $data['counters']['nodesDeleted'], - propertiesSet: $data['counters']['propertiesSet'], - relationshipsCreated: $data['counters']['relationshipsCreated'], - relationshipsDeleted: $data['counters']['relationshipsDeleted'], - labelsAdded: $data['counters']['labelsAdded'], - labelsRemoved: $data['counters']['labelsRemoved'], - indexesAdded: $data['counters']['indexesAdded'], - indexesRemoved: $data['counters']['indexesRemoved'], - constraintsAdded: $data['counters']['constraintsAdded'], - constraintsRemoved: $data['counters']['constraintsRemoved'], - containsSystemUpdates: $data['counters']['containsSystemUpdates'], - systemUpdates: $data['counters']['systemUpdates'] + containsUpdates: $data['counters']['containsUpdates'] ?? false, + nodesCreated: $data['counters']['nodesCreated'] ?? 0, + nodesDeleted: $data['counters']['nodesDeleted'] ?? 0, + propertiesSet: $data['counters']['propertiesSet'] ?? 0, + relationshipsCreated: $data['counters']['relationshipsCreated'] ?? 0, + relationshipsDeleted: $data['counters']['relationshipsDeleted'] ?? 0, + labelsAdded: $data['counters']['labelsAdded'] ?? 0, + labelsRemoved: $data['counters']['labelsRemoved'] ?? 0, + indexesAdded: $data['counters']['indexesAdded'] ?? 0, + indexesRemoved: $data['counters']['indexesRemoved'] ?? 0, + constraintsAdded: $data['counters']['constraintsAdded'] ?? 0, + constraintsRemoved: $data['counters']['constraintsRemoved'] ?? 0, + containsSystemUpdates: $data['counters']['containsSystemUpdates'] ?? false, + systemUpdates: $data['counters']['systemUpdates'] ?? 0 ), $profile ); @@ -111,10 +102,8 @@ public function run(string $cypher, array $parameters = [], string $database = ' if ($response !== null) { $contents = $response->getBody()->getContents(); $errorResponse = json_decode($contents, true); - throw Neo4jException::fromNeo4jResponse($errorResponse, $e); } - throw $e; } } @@ -132,27 +121,36 @@ public function beginTransaction(string $database = 'neo4j'): Transaction private function createProfileData(array $data): ProfiledQueryPlan { + $ogm = new OGM(); + + // Map arguments using OGM $arguments = $data['arguments']; + $mappedArguments = []; + foreach ($arguments as $key => $value) { + $mappedArguments[$key] = $ogm->map($value); + } $queryArguments = new QueryArguments( - $arguments['globalMemory'] ?? 0, - $arguments['plannerImpl'] ?? '', - $arguments['memory'] ?? 0, - $arguments['stringRepresentation'] ?? '', - is_string($arguments['runtime'] ?? '') ? $arguments['runtime'] : json_encode($arguments['runtime']), - $arguments['runtimeImpl'] ?? '', - $arguments['dbHits'] ?? 0, - $arguments['batchSize'] ?? 0, - $arguments['details'] ?? '', - $arguments['plannerVersion'] ?? '', - $arguments['pipelineInfo'] ?? '', - $arguments['runtimeVersion'] ?? '', - $arguments['id'] ?? 0, - $arguments['estimatedRows'] ?? 0.0, - is_string($arguments['planner'] ?? '') ? $arguments['planner'] : json_encode($arguments['planner']), - $arguments['rows'] ?? 0 + $mappedArguments['globalMemory'], + $mappedArguments['plannerImpl'], + $mappedArguments['memory'], + $mappedArguments['stringRepresentation'], + is_string($mappedArguments['runtime'] ? $mappedArguments['runtime'] : json_encode($mappedArguments['runtime'])), + $mappedArguments['time'], + $mappedArguments['runtimeImpl'], + $mappedArguments['dbHits'], + $mappedArguments['batchSize'], + $mappedArguments['details'], + $mappedArguments['plannerVersion'], + $mappedArguments['pipelineInfo'], + $mappedArguments['runtimeVersion'], + $mappedArguments['id'], + (float)($mappedArguments['estimatedRows'] ?? 0.0), + is_string($mappedArguments['planner'] ? $mappedArguments['planner'] : json_encode($mappedArguments['planner'])), + $mappedArguments['rows'] ); + $profiledQueryPlan = new ProfiledQueryPlan( $data['dbHits'], $data['records'], @@ -165,14 +163,13 @@ private function createProfileData(array $data): ProfiledQueryPlan $queryArguments ); - foreach($data['children'] as $child) { + // Process children recursively + foreach ($data['children'] as $child) { $childQueryPlan = $this->createProfileData($child); - $profiledQueryPlan->addChild($childQueryPlan); } return $profiledQueryPlan; } - } diff --git a/src/Objects/QueryArguments.php b/src/Objects/QueryArguments.php index dbee8c92..5d7fdf55 100644 --- a/src/Objects/QueryArguments.php +++ b/src/Objects/QueryArguments.php @@ -4,57 +4,26 @@ class QueryArguments { - private int $globalMemory; - private string $plannerImpl; - private int $memory; - private string $stringRepresentation; - private string $runtime; - private string $runtimeImpl; - private int $dbHits; - private int $batchSize; - private string $details; - private string $plannerVersion; - private string $pipelineInfo; - private string $runtimeVersion; - private int $id; - private float $estimatedRows; - private string $planner; - private int $rows; - public function __construct( - ?int $globalMemory = 0, - ?string $plannerImpl = '', - ?int $memory = 0, - ?string $stringRepresentation = '', - $runtime = '', - ?string $runtimeImpl = '', - ?int $dbHits = 0, - ?int $batchSize = 0, - ?string $details = '', - ?string $plannerVersion = '', - ?string $pipelineInfo = '', - ?string $runtimeVersion = '', - ?int $id = 0, - ?float $estimatedRows = 0.0, - ?string $planner = '', - ?int $rows = 0 - ) { - $this->globalMemory = $globalMemory ?? 0; - $this->plannerImpl = $plannerImpl ?? ''; - $this->memory = $memory ?? 0; - $this->stringRepresentation = $stringRepresentation ?? ''; - $this->runtime = is_string($runtime) ? $runtime : json_encode($runtime); - $this->runtimeImpl = $runtimeImpl ?? ''; - $this->dbHits = $dbHits ?? 0; - $this->batchSize = $batchSize ?? 0; - $this->details = $details ?? ''; - $this->plannerVersion = $plannerVersion ?? ''; - $this->pipelineInfo = $pipelineInfo ?? ''; - $this->runtimeVersion = $runtimeVersion ?? ''; - $this->id = $id ?? 0; - $this->estimatedRows = $estimatedRows ?? 0.0; - $this->planner = $planner ?? ''; - $this->rows = $rows ?? 0; + private readonly ?int $globalMemory = null, + private readonly ?string $plannerImpl = null, + private readonly ?int $memory = null, + private readonly ?string $stringRepresentation = null, + private readonly ?string $runtime = null, + private readonly ?int $time = null, + private readonly ?string $runtimeImpl = null, + private readonly ?int $dbHits = null, + private readonly ?int $batchSize = null, + private readonly ?string $details = null, + private readonly ?string $plannerVersion = null, + private readonly ?string $pipelineInfo = null, + private readonly ?string $runtimeVersion = null, + private readonly ?int $id = null, + private readonly ?float $estimatedRows = null, + private readonly ?string $planner = null, + private readonly ?int $rows = null + ) + { } public function getGlobalMemory(): int @@ -82,6 +51,11 @@ public function getRuntime(): string return $this->runtime; } + public function getTime(): int + { + return $this->time; + } + public function getRuntimeImpl(): string { return $this->runtimeImpl; diff --git a/tests/Integration/Neo4jQueryAPIIntegrationTest.php b/tests/Integration/Neo4jQueryAPIIntegrationTest.php index aada3a36..02c1cd85 100644 --- a/tests/Integration/Neo4jQueryAPIIntegrationTest.php +++ b/tests/Integration/Neo4jQueryAPIIntegrationTest.php @@ -2,7 +2,11 @@ namespace Neo4j\QueryAPI\Tests\Integration; +use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Psr7\Response; use Neo4j\QueryAPI\Exception\Neo4jException; use Neo4j\QueryAPI\Neo4jQueryAPI; use Neo4j\QueryAPI\Objects\ProfiledQueryPlan; @@ -135,7 +139,7 @@ public function testProfileCreateWatchedWithFilters(): void $this->assertNotNull($result->getProfiledQueryPlan(), "profiled query plan not found"); } - public function testProfileCreateKnowsBidirectionalRelationships(): void + public function testProfileCreateKnowsBidirectionalRelationshipsMock(): void { $query = " PROFILE UNWIND range(1, 100) AS i @@ -145,8 +149,20 @@ public function testProfileCreateKnowsBidirectionalRelationships(): void CREATE (a)-[:KNOWS]->(b), (b)-[:KNOWS]->(a); "; - $result = $this->api->run($query); - $this->assertNotNull($result->getProfiledQueryPlan(), "profiled query plan not found"); + $mockSack = new MockHandler([ + new Response(200, [], file_get_contents(__DIR__ . '/../resources/responses/complex-query-profile.json')), + ]); + + $handler = HandlerStack::create($mockSack); + $client = new Client(['handler' => $handler]); + $api = new Neo4jQueryAPI($client); + + $result = $api->run($query); + $plan = $result->getProfiledQueryPlan(); + + $expected = require __DIR__.'/../resources/expected/complex-query-profile.php'; + + $this->assertEquals($expected, "profiled query plan not found"); } public function testProfileCreateActedInRelationships(): void @@ -162,6 +178,7 @@ public function testProfileCreateActedInRelationships(): void $this->assertNotNull($result->getProfiledQueryPlan(), "profiled query plan not found"); } + public function testChildQueryPlanExistence(): void { $result = $this->api->run("PROFILE MATCH (n:Person {name: 'Alice'}) RETURN n.name"); @@ -176,6 +193,7 @@ public function testChildQueryPlanExistence(): void } + public function testTransactionCommit(): void { // Begin a new transaction @@ -226,7 +244,7 @@ private function populateTestData(): void /** * @throws GuzzleException */ - #[DataProvider(methodName: 'queryProvider')] + /*#[DataProvider(methodName: 'queryProvider')] public function testRunSuccessWithParameters( string $query, array $parameters, @@ -235,7 +253,7 @@ public function testRunSuccessWithParameters( { $results = $this->api->run($query, $parameters); $this->assertEquals($expectedResults, $results); - } + }*/ public function testInvalidQueryException(): void { diff --git a/tests/resources/expected/complex-query-profile.php b/tests/resources/expected/complex-query-profile.php new file mode 100644 index 00000000..2ba57f3a --- /dev/null +++ b/tests/resources/expected/complex-query-profile.php @@ -0,0 +1,72 @@ +(b), (b)-[anon_1:KNOWS]->(a) | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +Filter | 3 | cache[a.id] < cache[b.id] | 2 | 0 | 0 | | 0/0 | 0.000 | In Pipeline 3 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Apply | 4 | | 8 | 0 | 0 | | 0/0 | | |\n| |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +CartesianProduct | 5 | | 8 | 0 | 0 | 1392 | | | In Pipeline 3 |\n| | |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | | +Filter | 6 | cache[b.id] = j | 50 | 0 | 0 | | | | |\n| | | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | | +NodeByLabelScan | 7 | b:Person | 1000 | 0 | 0 | 256 | 0/0 | 0.000 | Fused in Pipeline 2 |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +Filter | 8 | rand() < $autodouble_4 AND cache[a.id] = i | 15 | 0 | 2027 | | | | |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | +NodeByLabelScan | 9 | a:Person | 1000 | 20000 | 30000 | 8488 | 10002/0 | 6.158 | Fused in Pipeline 1 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Unwind | 10 | range($autoint_2, $autoint_3) AS j | 100 | 10000 | 0 | | | | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| +Unwind | 11 | range($autoint_0, $autoint_1) AS i | 10 | 100 | 0 | | 0/0 | 0.000 | Fused in Pipeline 0 |\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n\nTotal database accesses: 32027, total allocated memory: 10624\n" + "runtime" : "PIPELINED", + "Time" : 0, + "runtime-impl" : "PIPELINED", + "version" : 5, + "DbHits" :0, + "batch-size" : 128, + "Details" : "", + "planner-version" : 5.26, + "PipelineInfo" : "In Pipeline 3", + "runtime-version" :5.26, + "Id" : 0, + "PageCacheMisses" : 0, + "EstimatedRows" : 2.25, + "planner" : "COST", + "Rows" : 0, + "PageCacheHits" : 0 + }, + "identifiers" : [ "j", "a", "i", "b", "anon_0", "anon_1" ], + "children" : [ { + "dbHits" : 0, + "records" : 0, + "hasPageCacheStats" : false, + "pageCacheHits" : 0, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 0.0, + "time" : 0, + "operatorType" : "EmptyResult@neo4j", + "arguments" : { + "PipelineInfo" : "In Pipeline 3", + "Time" : 0, + "Id" : 1, + "PageCacheMisses" : 0, + "EstimatedRows" : 2.25, + "DbHits" : 0, + "Rows" :0, + "PageCacheHits" :0 + }, + "identifiers" : [ "j", "a", "i", "b", "anon_0", "anon_1" ], + "children" : [ { + "dbHits" : 0, + "records" : 0, + "hasPageCacheStats" : false, + "pageCacheHits" : 0, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 0.0, + "time" : 0, + "operatorType" : "Create@neo4j", + "arguments" : { + "Details" : { + "$type" : "String", + "_value" : "(a)-[anon_0:KNOWS]->(b), (b)-[anon_1:KNOWS]->(a)" + }, + "PipelineInfo" : { + "$type" : "String", + "_value" : "In Pipeline 3" + }, + "Time" : { + "$type" : "Integer", + "_value" : "0" + }, + "Id" : { + "$type" : "Integer", + "_value" : "2" + }, + "PageCacheMisses" : { + "$type" : "Integer", + "_value" : "0" + }, + "EstimatedRows" : { + "$type" : "Float", + "_value" : "2.25" + }, + "DbHits" : { + "$type" : "Integer", + "_value" : "0" + }, + "Rows" : { + "$type" : "Integer", + "_value" : "0" + }, + "PageCacheHits" : { + "$type" : "Integer", + "_value" : "0" + } + }, + "identifiers" : [ "j", "a", "i", "b", "anon_0", "anon_1" ], + "children" : [ { + "dbHits" : 0, + "records" : 0, + "hasPageCacheStats" : false, + "pageCacheHits" : 0, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 0.0, + "time" : 0, + "operatorType" : "Filter@neo4j", + "arguments" : { + "Details" : { + "$type" : "String", + "_value" : "cache[a.id] < cache[b.id]" + }, + "PipelineInfo" : { + "$type" : "String", + "_value" : "In Pipeline 3" + }, + "Time" : { + "$type" : "Integer", + "_value" : "0" + }, + "Id" : { + "$type" : "Integer", + "_value" : "3" + }, + "PageCacheMisses" : { + "$type" : "Integer", + "_value" : "0" + }, + "EstimatedRows" : { + "$type" : "Float", + "_value" : "2.25" + }, + "DbHits" : { + "$type" : "Integer", + "_value" : "0" + }, + "Rows" : { + "$type" : "Integer", + "_value" : "0" + }, + "PageCacheHits" : { + "$type" : "Integer", + "_value" : "0" + } + }, + "identifiers" : [ "i", "j", "a", "b" ], + "children" : [ { + "dbHits" : 0, + "records" : 0, + "hasPageCacheStats" : false, + "pageCacheHits" : 0, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 0.0, + "time" : 0, + "operatorType" : "Apply@neo4j", + "arguments" : { + "Id" : { + "$type" : "Integer", + "_value" : "4" + }, + "PageCacheMisses" : { + "$type" : "Integer", + "_value" : "0" + }, + "EstimatedRows" : { + "$type" : "Float", + "_value" : "7.5" + }, + "DbHits" : { + "$type" : "Integer", + "_value" : "0" + }, + "Rows" : { + "$type" : "Integer", + "_value" : "0" + }, + "PageCacheHits" : { + "$type" : "Integer", + "_value" : "0" + } + }, + "identifiers" : [ "i", "j", "a", "b" ], + "children" : [ { + "dbHits" : 0, + "records" : 10000, + "hasPageCacheStats" : false, + "pageCacheHits" : 0, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 0.0, + "time" : 0, + "operatorType" : "Unwind@neo4j", + "arguments" : { + "Details" : { + "$type" : "String", + "_value" : "range($autoint_2, $autoint_3) AS j" + }, + "PipelineInfo" : { + "$type" : "String", + "_value" : "Fused in Pipeline 0" + }, + "Id" : { + "$type" : "Integer", + "_value" : "10" + }, + "EstimatedRows" : { + "$type" : "Float", + "_value" : "100.0" + }, + "DbHits" : { + "$type" : "Integer", + "_value" : "0" + }, + "Rows" : { + "$type" : "Integer", + "_value" : "10000" + } + }, + "identifiers" : [ "i", "j" ], + "children" : [ { + "dbHits" : 0, + "records" : 100, + "hasPageCacheStats" : false, + "pageCacheHits" : 0, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 0.0, + "time" : 0, + "operatorType" : "Unwind@neo4j", + "arguments" : { + "Details" : { + "$type" : "String", + "_value" : "range($autoint_0, $autoint_1) AS i" + }, + "PipelineInfo" : { + "$type" : "String", + "_value" : "Fused in Pipeline 0" + }, + "Time" : { + "$type" : "Integer", + "_value" : "0" + }, + "Id" : { + "$type" : "Integer", + "_value" : "11" + }, + "PageCacheMisses" : { + "$type" : "Integer", + "_value" : "0" + }, + "EstimatedRows" : { + "$type" : "Float", + "_value" : "10.0" + }, + "DbHits" : { + "$type" : "Integer", + "_value" : "0" + }, + "Rows" : { + "$type" : "Integer", + "_value" : "100" + }, + "PageCacheHits" : { + "$type" : "Integer", + "_value" : "0" + } + }, + "identifiers" : [ "i" ], + "children" : [ ] + } ] + }, { + "dbHits" : 0, + "records" : 0, + "hasPageCacheStats" : false, + "pageCacheHits" : 0, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 0.0, + "time" : 0, + "operatorType" : "CartesianProduct@neo4j", + "arguments" : { + "Memory" : { + "$type" : "Integer", + "_value" : "1392" + }, + "PipelineInfo" : { + "$type" : "String", + "_value" : "In Pipeline 3" + }, + "Id" : { + "$type" : "Integer", + "_value" : "5" + }, + "EstimatedRows" : { + "$type" : "Float", + "_value" : "7.5" + }, + "DbHits" : { + "$type" : "Integer", + "_value" : "0" + }, + "Rows" : { + "$type" : "Integer", + "_value" : "0" + } + }, + "identifiers" : [ "i", "j", "a", "b" ], + "children" : [ { + "dbHits" : 2027, + "records" : 0, + "hasPageCacheStats" : false, + "pageCacheHits" : 0, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 0.0, + "time" : 0, + "operatorType" : "Filter@neo4j", + "arguments" : { + "Details" : { + "$type" : "String", + "_value" : "rand() < $autodouble_4 AND cache[a.id] = i" + }, + "PipelineInfo" : { + "$type" : "String", + "_value" : "Fused in Pipeline 1" + }, + "Id" : { + "$type" : "Integer", + "_value" : "8" + }, + "EstimatedRows" : { + "$type" : "Float", + "_value" : "15.0" + }, + "DbHits" : { + "$type" : "Integer", + "_value" : "2027" + }, + "Rows" : { + "$type" : "Integer", + "_value" : "0" + } + }, + "identifiers" : [ "i", "j", "a" ], + "children" : [ { + "dbHits" : 30000, + "records" : 20000, + "hasPageCacheStats" : true, + "pageCacheHits" : 10002, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 1.0, + "time" : 6157670, + "operatorType" : "NodeByLabelScan@neo4j", + "arguments" : { + "Details" : { + "$type" : "String", + "_value" : "a:Person" + }, + "PipelineInfo" : { + "$type" : "String", + "_value" : "Fused in Pipeline 1" + }, + "Memory" : { + "$type" : "Integer", + "_value" : "8488" + }, + "Time" : { + "$type" : "Integer", + "_value" : "6157670" + }, + "Id" : { + "$type" : "Integer", + "_value" : "9" + }, + "EstimatedRows" : { + "$type" : "Float", + "_value" : "1000.0" + }, + "PageCacheMisses" : { + "$type" : "Integer", + "_value" : "0" + }, + "DbHits" : { + "$type" : "Integer", + "_value" : "30000" + }, + "Rows" : { + "$type" : "Integer", + "_value" : "20000" + }, + "PageCacheHits" : { + "$type" : "Integer", + "_value" : "10002" + } + }, + "identifiers" : [ "i", "j", "a" ], + "children" : [ ] + } ] + }, { + "dbHits" : 0, + "records" : 0, + "hasPageCacheStats" : false, + "pageCacheHits" : 0, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 0.0, + "time" : 0, + "operatorType" : "Filter@neo4j", + "arguments" : { + "Details" : { + "$type" : "String", + "_value" : "cache[b.id] = j" + }, + "PipelineInfo" : { + "$type" : "String", + "_value" : "Fused in Pipeline 2" + }, + "Id" : { + "$type" : "Integer", + "_value" : "6" + }, + "EstimatedRows" : { + "$type" : "Float", + "_value" : "50.0" + }, + "DbHits" : { + "$type" : "Integer", + "_value" : "0" + }, + "Rows" : { + "$type" : "Integer", + "_value" : "0" + } + }, + "identifiers" : [ "i", "j", "b" ], + "children" : [ { + "dbHits" : 0, + "records" : 0, + "hasPageCacheStats" : false, + "pageCacheHits" : 0, + "pageCacheMisses" : 0, + "pageCacheHitRatio" : 0.0, + "time" : 0, + "operatorType" : "NodeByLabelScan@neo4j", + "arguments" : { + "Details" : { + "$type" : "String", + "_value" : "b:Person" + }, + "PipelineInfo" : { + "$type" : "String", + "_value" : "Fused in Pipeline 2" + }, + "Memory" : { + "$type" : "Integer", + "_value" : "256" + }, + "Time" : { + "$type" : "Integer", + "_value" : "0" + }, + "Id" : { + "$type" : "Integer", + "_value" : "7" + }, + "EstimatedRows" : { + "$type" : "Float", + "_value" : "1000.0" + }, + "PageCacheMisses" : { + "$type" : "Integer", + "_value" : "0" + }, + "DbHits" : { + "$type" : "Integer", + "_value" : "0" + }, + "Rows" : { + "$type" : "Integer", + "_value" : "0" + }, + "PageCacheHits" : { + "$type" : "Integer", + "_value" : "0" + } + }, + "identifiers" : [ "i", "j", "b" ], + "children" : [ ] + } ] + } ] + } ] + } ] + } ] + } ] + } ] + }, + "bookmarks" : [ "FB:kcwQMSScZToiRKKW8P2Tlr362soAAQWHkA==" ] +} \ No newline at end of file From c0fb3344ecab987be1cdf3c8b136554ed471e437 Mon Sep 17 00:00:00 2001 From: Pratiksha Date: Fri, 10 Jan 2025 17:56:44 +0530 Subject: [PATCH 2/9] winp --- src/Neo4jQueryAPI.php | 5 +- src/Objects/ProfiledQueryPlan.php | 9 +- ...nts.php => ProfiledQueryPlanArguments.php} | 12 +- src/Results/ResultSet.php | 2 +- .../expected/complex-query-profile.php | 239 +++++++++++++++++- .../responses/complex-query-profile.json | 2 +- 6 files changed, 254 insertions(+), 15 deletions(-) rename src/Objects/{QueryArguments.php => ProfiledQueryPlanArguments.php} (87%) diff --git a/src/Neo4jQueryAPI.php b/src/Neo4jQueryAPI.php index 7394995b..7d8a0223 100644 --- a/src/Neo4jQueryAPI.php +++ b/src/Neo4jQueryAPI.php @@ -7,7 +7,7 @@ use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\RequestException; use Neo4j\QueryAPI\Objects\ChildQueryPlan; -use Neo4j\QueryAPI\Objects\QueryArguments; +use Neo4j\QueryAPI\Objects\ProfiledQueryPlanArguments; use Neo4j\QueryAPI\Objects\ResultCounters; use Neo4j\QueryAPI\Objects\ProfiledQueryPlan; use Neo4j\QueryAPI\Results\ResultRow; @@ -136,13 +136,14 @@ private function createProfileData(array $data): ProfiledQueryPlan $mappedArguments[$key] = $ogm->map($value); } - $queryArguments = new QueryArguments( + $queryArguments = new ProfiledQueryPlanArguments( $mappedArguments['globalMemory'], $mappedArguments['plannerImpl'], $mappedArguments['memory'], $mappedArguments['stringRepresentation'], is_string($mappedArguments['runtime'] ? $mappedArguments['runtime'] : json_encode($mappedArguments['runtime'])), $mappedArguments['time'], + $mappedArguments['pageCacheMisses'], $mappedArguments['runtimeImpl'], $mappedArguments['dbHits'], $mappedArguments['batchSize'], diff --git a/src/Objects/ProfiledQueryPlan.php b/src/Objects/ProfiledQueryPlan.php index 9e20f4e6..0e6aa670 100644 --- a/src/Objects/ProfiledQueryPlan.php +++ b/src/Objects/ProfiledQueryPlan.php @@ -2,7 +2,7 @@ namespace Neo4j\QueryAPI\Objects; -class ProfiledQueryPlan +class ProfiledQueryPlan extends \Neo4j\QueryAPI\Objects\Bookmarks { private int $dbHits; private int $records; @@ -12,7 +12,7 @@ class ProfiledQueryPlan private float $pageCacheHitRatio; private int $time; private string $operatorType; - private QueryArguments $arguments; + private ProfiledQueryPlanArguments $arguments; /** * @var list @@ -28,7 +28,8 @@ public function __construct( ?float $pageCacheHitRatio = 0.0, ?int $time = 0, ?string $operatorType = '', - QueryArguments $arguments + ProfiledQueryPlanArguments $arguments, + ) { $this->dbHits = $dbHits ?? 0; $this->records = $records ?? 0; @@ -81,7 +82,7 @@ public function getOperatorType(): string return $this->operatorType; } - public function getArguments(): QueryArguments + public function getArguments(): ProfiledQueryPlanArguments { return $this->arguments; } diff --git a/src/Objects/QueryArguments.php b/src/Objects/ProfiledQueryPlanArguments.php similarity index 87% rename from src/Objects/QueryArguments.php rename to src/Objects/ProfiledQueryPlanArguments.php index 5d7fdf55..e61a7c37 100644 --- a/src/Objects/QueryArguments.php +++ b/src/Objects/ProfiledQueryPlanArguments.php @@ -2,7 +2,7 @@ namespace Neo4j\QueryAPI\Objects; -class QueryArguments +class ProfiledQueryPlanArguments { public function __construct( private readonly ?int $globalMemory = null, @@ -11,6 +11,8 @@ public function __construct( private readonly ?string $stringRepresentation = null, private readonly ?string $runtime = null, private readonly ?int $time = null, + private readonly ?int $pageCacheMisses = null, + private readonly ?int $pageCacheHits = null, private readonly ?string $runtimeImpl = null, private readonly ?int $dbHits = null, private readonly ?int $batchSize = null, @@ -55,7 +57,15 @@ public function getTime(): int { return $this->time; } + public function getPageCacheMisses(): int + { + return $this->pageCacheMisses; + } + private function getPageCacheHits():int + { + return $this->pageCacheHits; + } public function getRuntimeImpl(): string { return $this->runtimeImpl; diff --git a/src/Results/ResultSet.php b/src/Results/ResultSet.php index 3f25cfc4..a1d4068a 100644 --- a/src/Results/ResultSet.php +++ b/src/Results/ResultSet.php @@ -7,7 +7,7 @@ use IteratorAggregate; use Neo4j\QueryAPI\Objects\ChildQueryPlan; use Neo4j\QueryAPI\Objects\ProfiledQueryPlan; -use Neo4j\QueryAPI\Objects\QueryArguments; +use Neo4j\QueryAPI\Objects\ProfiledQueryPlanArguments; use Neo4j\QueryAPI\Objects\ResultCounters; use Neo4j\QueryAPI\Objects\Bookmarks; // Make sure to include the Bookmarks class use Traversable; diff --git a/tests/resources/expected/complex-query-profile.php b/tests/resources/expected/complex-query-profile.php index 2ba57f3a..5234ba60 100644 --- a/tests/resources/expected/complex-query-profile.php +++ b/tests/resources/expected/complex-query-profile.php @@ -1,7 +1,7 @@ (b), (b)-[anon_1:KNOWS]->(a)", + null, + "In Pipeline 3", + null, + 2, + 2.25, + null, + 0 + ) + ), + [ + new ProfiledQueryPlan( + 0, + 0, + false, + 0, + 0, + 0.0, + 0, + "Filter@neo4j", + new ProfiledQueryPlanArguments( + null, + null, + null, + null, + null, + 0, + 0, + 0, + null, + 0, + null, + "cache[a.id] < cache[b.id]", + null, + "In Pipeline 3", + null, + 3, + 2.25, + null, + 0 + ) + ), + [ + new ProfiledQueryPlan( + 0, + 0, + false, + 0, + 0, + 0.0, + 0, + "Apply@neo4j", + new ProfiledQueryPlanArguments( + null, + null, + null, + null, + null, + 0, + 0, + 0, + null, + 0, + null, + null, + null, + null, + null, + 4, + 7.5, + null, + 0 + ) + ), + [ + new ProfiledQueryPlan( + 0, + 10000, + false, + 0, + 0, + 0.0, + 0, + "Unwind@neo4j", + new ProfiledQueryPlanArguments( + null, + null, + null, + null, + null, + 0, + 0, + 0, + null, + 0, + null, + "range($autoint_2, $autoint_3) AS j", + null, + "Fused in Pipeline 0", + null, + 10, + 100.0, + null, + 10000 + ) + ), + [ + new ProfiledQueryPlan( + 0, + 100, + false, + 0, + 0, + 0.0, + 0, + "Unwind@neo4j", + new ProfiledQueryPlanArguments( + null, + null, + null, + null, + null, + 0, + 0, + 0, + null, + 0, + null, + "range($autoint_0, $autoint_1) AS i", + null, + "Fused in Pipeline 0", + null, + 11, + 10.0, + null, + 100 + ) + ), + [ + [ + new ProfiledQueryPlan( + 0, + 0, + false, + 0, + 0, + 0.0, + 0, + "CartesianProduct@neo4j", + new ProfiledQueryPlanArguments( + null, + null, + 1392, + null, + null, + 0, + 0, + 0, + null, + 0, + null, + null, + null, + "In Pipeline 3", + null, + 5, + 7.5, + null, + 0 + ) + ) + ] - ) + ] + ] + + ] + + ] + + ] + + + ] ) ] + + + + ) + ); \ No newline at end of file diff --git a/tests/resources/responses/complex-query-profile.json b/tests/resources/responses/complex-query-profile.json index e2ccce03..505de58a 100644 --- a/tests/resources/responses/complex-query-profile.json +++ b/tests/resources/responses/complex-query-profile.json @@ -298,7 +298,7 @@ } }, "identifiers" : [ "i" ], - "children" : [ ] + "children" : [ ] /*till here */ } ] }, { "dbHits" : 0, From 8d688c83379242eea0c5c6bf50186d6ef7017710 Mon Sep 17 00:00:00 2001 From: Pratiksha Date: Mon, 13 Jan 2025 18:02:53 +0530 Subject: [PATCH 3/9] winp --- src/Neo4jQueryAPI.php | 1 - src/Objects/ProfiledQueryPlan.php | 13 +- src/Results/ResultSet.php | 3 +- .../expected/complex-query-profile.php | 166 +++++++++++++++++- .../responses/complex-query-profile.json | 2 +- 5 files changed, 170 insertions(+), 15 deletions(-) diff --git a/src/Neo4jQueryAPI.php b/src/Neo4jQueryAPI.php index 7d8a0223..71198a84 100644 --- a/src/Neo4jQueryAPI.php +++ b/src/Neo4jQueryAPI.php @@ -6,7 +6,6 @@ use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\RequestException; -use Neo4j\QueryAPI\Objects\ChildQueryPlan; use Neo4j\QueryAPI\Objects\ProfiledQueryPlanArguments; use Neo4j\QueryAPI\Objects\ResultCounters; use Neo4j\QueryAPI\Objects\ProfiledQueryPlan; diff --git a/src/Objects/ProfiledQueryPlan.php b/src/Objects/ProfiledQueryPlan.php index 0e6aa670..14251129 100644 --- a/src/Objects/ProfiledQueryPlan.php +++ b/src/Objects/ProfiledQueryPlan.php @@ -15,7 +15,7 @@ class ProfiledQueryPlan extends \Neo4j\QueryAPI\Objects\Bookmarks private ProfiledQueryPlanArguments $arguments; /** - * @var list + * @var list */ private array $children; @@ -28,8 +28,8 @@ public function __construct( ?float $pageCacheHitRatio = 0.0, ?int $time = 0, ?string $operatorType = '', - ProfiledQueryPlanArguments $arguments, - + ProfiledQueryPlanArguments $arguments , + array $children = [] // Accept an array of children, default to empty array ) { $this->dbHits = $dbHits ?? 0; $this->records = $records ?? 0; @@ -40,6 +40,7 @@ public function __construct( $this->time = $time ?? 0; $this->operatorType = $operatorType ?? ''; $this->arguments = $arguments; + $this->children = $children ?? []; } public function getDbHits(): int @@ -88,14 +89,14 @@ public function getArguments(): ProfiledQueryPlanArguments } /** - * @return list + * @return list */ - public function getChildren(): array + public function getChildren(): array { return $this->children; } - public function addChild(ProfiledQueryPlan $child): void + public function addChild(ProfiledQueryPlan|ProfiledQueryPlanArguments $child): void { $this->children[] = $child; } diff --git a/src/Results/ResultSet.php b/src/Results/ResultSet.php index a1d4068a..418cc5cf 100644 --- a/src/Results/ResultSet.php +++ b/src/Results/ResultSet.php @@ -21,7 +21,8 @@ public function __construct( private readonly array $rows, private ResultCounters $counters, private Bookmarks $bookmarks, - private ?ProfiledQueryPlan $profiledQueryPlan = null + private ?ProfiledQueryPlan $profiledQueryPlan = null, + private ?ProfiledQueryPlanArguments $profiledQueryPlanArguments = null ) { } diff --git a/tests/resources/expected/complex-query-profile.php b/tests/resources/expected/complex-query-profile.php index 5234ba60..5525ee40 100644 --- a/tests/resources/expected/complex-query-profile.php +++ b/tests/resources/expected/complex-query-profile.php @@ -199,7 +199,7 @@ null, 0, null, - "range($autoint_2, $autoint_3) AS j", + "range(\$autoint_2, \$autoint_3) AS j", null, "Fused in Pipeline 0", null, @@ -231,7 +231,7 @@ null, 0, null, - "range($autoint_0, $autoint_1) AS i", + "range(\$autoint_0, \$autoint_1) AS i", null, "Fused in Pipeline 0", null, @@ -273,7 +273,164 @@ null, 0 ) - ) + ), + + [ + new ProfiledQueryPlan( + 0, + 0, + false, + 0, + 0, + 0.0, + 0, + "CartesianProduct@neo4j", + new ProfiledQueryPlanArguments( + null, + null, + 1392, + null, + null, + 0, + 0, + 0, + null, + 0, + null, + null, + null, + "In Pipeline 3", + null, + 5, + 7.5, + null, + 0 + ) + ), + new ProfiledQueryPlan( + 2027, + 0, + false, + 0, + 0, + 0.0, + 0, + "Filter@neo4j", + new ProfiledQueryPlanArguments( + "rand() < \$autodouble_4 AND cache[a.id] = i", + "Fused in Pipeline 1", + 8, + null, + null, + 2027, + 0, + 0, + null, + 0, + null, + null, + null, + null, + null, + 15.0, + null, + 0 + ) + ), + new ProfiledQueryPlan( + 30000, + 20000, + true, + 10002, + 0, + 1.0, + 6157670, + "NodeByLabelScan@neo4j", + new ProfiledQueryPlanArguments( + "a:Person", + "Fused in Pipeline 1", + 9, + null, + null, + 30000, + 20000, + 0, + null, + 10002, + null, + null, + null, + null, + null, + 1000.0, + null, + 6157670 + ) + ), + new ProfiledQueryPlan( + 0, + 0, + false, + 0, + 0, + 0.0, + 0, + "Filter@neo4j", + new ProfiledQueryPlanArguments( + "cache[b.id] = j", + "Fused in Pipeline 2", + 6, + null, + null, + 0, + 0, + 0, + null, + 0, + null, + null, + null, + null, + null, + 50.0, + null, + 0 + ) + ), + + new ProfiledQueryPlan( + 0, + 0, + false, + 0, + 0, + 0.0, + 0, + "NodeByLabelScan@neo4j", + new ProfiledQueryPlanArguments( + "b:Person", + "Fused in Pipeline 2", + 7, + null, + null, + 0, + 0, + 0, + null, + 0, + null, + null, + null, + null, + null, + 1000.0, + null, + 0 + ) + ) + + ] + ] ] @@ -290,9 +447,6 @@ ) ] - - - ) diff --git a/tests/resources/responses/complex-query-profile.json b/tests/resources/responses/complex-query-profile.json index 505de58a..43bf0e5c 100644 --- a/tests/resources/responses/complex-query-profile.json +++ b/tests/resources/responses/complex-query-profile.json @@ -43,7 +43,7 @@ "arguments" : { "GlobalMemory" : 10624, "planner-impl" : "IDP", - "string-representation" : "Cypher 5\n\nPlanner COST\n\nRuntime PIPELINED\n\nRuntime version 5.26\n\nBatch size 128\n\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline |\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +ProduceResults | 0 | | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +EmptyResult | 1 | | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +Create | 2 | (a)-[anon_0:KNOWS]->(b), (b)-[anon_1:KNOWS]->(a) | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +Filter | 3 | cache[a.id] < cache[b.id] | 2 | 0 | 0 | | 0/0 | 0.000 | In Pipeline 3 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Apply | 4 | | 8 | 0 | 0 | | 0/0 | | |\n| |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +CartesianProduct | 5 | | 8 | 0 | 0 | 1392 | | | In Pipeline 3 |\n| | |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | | +Filter | 6 | cache[b.id] = j | 50 | 0 | 0 | | | | |\n| | | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | | +NodeByLabelScan | 7 | b:Person | 1000 | 0 | 0 | 256 | 0/0 | 0.000 | Fused in Pipeline 2 |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +Filter | 8 | rand() < $autodouble_4 AND cache[a.id] = i | 15 | 0 | 2027 | | | | |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | +NodeByLabelScan | 9 | a:Person | 1000 | 20000 | 30000 | 8488 | 10002/0 | 6.158 | Fused in Pipeline 1 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Unwind | 10 | range($autoint_2, $autoint_3) AS j | 100 | 10000 | 0 | | | | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| +Unwind | 11 | range($autoint_0, $autoint_1) AS i | 10 | 100 | 0 | | 0/0 | 0.000 | Fused in Pipeline 0 |\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n\nTotal database accesses: 32027, total allocated memory: 10624\n" + "string-representation" : "Cypher 5\n\nPlanner COST\n\nRuntime PIPELINED\n\nRuntime version 5.26\n\nBatch size 128\n\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline |\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +ProduceResults | 0 | | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +EmptyResult | 1 | | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +Create | 2 | (a)-[anon_0:KNOWS]->(b), (b)-[anon_1:KNOWS]->(a) | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +Filter | 3 | cache[a.id] < cache[b.id] | 2 | 0 | 0 | | 0/0 | 0.000 | In Pipeline 3 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Apply | 4 | | 8 | 0 | 0 | | 0/0 | | |\n| |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +CartesianProduct | 5 | | 8 | 0 | 0 | 1392 | | | In Pipeline 3 |\n| | |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | | +Filter | 6 | cache[b.id] = j | 50 | 0 | 0 | | | | |\n| | | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | | +NodeByLabelScan | 7 | b:Person | 1000 | 0 | 0 | 256 | 0/0 | 0.000 | Fused in Pipeline 2 |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +Filter | 8 | rand() < $autodouble_4 AND cache[a.id] = i | 15 | 0 | 2027 | | | | |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | +NodeByLabelScan | 9 | a:Person | 1000 | 20000 | 30000 | 8488 | 10002/0 | 6.158 | Fused in Pipeline 1 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Unwind | 10 | range($autoint_2, $autoint_3) AS j | 100 | 10000 | 0 | | | | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| +Unwind | 11 | range($autoint_0, $autoint_1) AS i | 10 | 100 | 0 | | 0/0 | 0.000 | Fused in Pipeline 0 |\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n\nTotal database accesses: 32027, total allocated memory: 10624\n", "runtime" : "PIPELINED", "Time" : 0, "runtime-impl" : "PIPELINED", From ae0a6cacab1b2438a3e6a7ff2e9bbeabfa27dc02 Mon Sep 17 00:00:00 2001 From: Pratiksha Date: Wed, 15 Jan 2025 17:57:03 +0530 Subject: [PATCH 4/9] winp --- .php-cs-fixer.cache | 1 + composer.json | 3 +- composer.lock | 4401 ++++++++++++----- src/Neo4jQueryAPI.php | 57 +- src/Objects/ProfiledQueryPlanArguments.php | 5 + .../Neo4jQueryAPIIntegrationTest.php | 28 +- .../expected/complex-query-profile.php | 172 +- .../responses/complex-query-profile.json | 22 +- 8 files changed, 3282 insertions(+), 1407 deletions(-) create mode 100644 .php-cs-fixer.cache diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache new file mode 100644 index 00000000..c2d9225a --- /dev/null +++ b/.php-cs-fixer.cache @@ -0,0 +1 @@ +{"php":"8.3.6","version":"3.68.0:v3.68.0#73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true},"hashes":{"src\/OGM.php":"93aae9c7afc8dbfd5aa00bc1d264ad19","src\/Neo4jQueryAPI.php":"30e5405ec8eb4b5dd202b9fb29f89d32","src\/Results\/ResultRow.php":"a355cae3f815c5b12e3eaf09200e9378","src\/Results\/ResultSet.php":"5f7748a356bf0fb30403e3c5a411bd24","src\/Exception\/Neo4jException.php":"891a142e4cb2932f8d3e6bcf9dffe630","src\/Profile.php":"4ee46fef850bdebf767af5cacaa97d32","src\/Objects\/Path.php":"278df6c382797caaac604186216180dd","src\/Objects\/Node.php":"565fcc90fdf0035b9d019541eea500cf","src\/Objects\/ProfiledQueryPlanArguments.php":"e1f4ba1e4701d9c3383eaee1a40c30cf","src\/Objects\/Person.php":"59814ca77fc40d172b232e7c8a638c39","src\/Objects\/Point.php":"085b951053c0edece358b89b5afeac7d","src\/Objects\/ProfiledQueryPlan.php":"4709c2a11e73003fc1c027a6a8a62971","src\/Objects\/Bookmarks.php":"e9a1155f1d871e20880b5d92f92a60cd","src\/Objects\/ResultCounters.php":"548cf41b8590b5e366002a5f80d15ed1","src\/Objects\/Relationship.php":"7bff01461f7156c81c0ab94ca8a6bf53","src\/Transaction.php":"cba4e1ad958b2d15952b74148fd96c21"}} \ No newline at end of file diff --git a/composer.json b/composer.json index 5e0b0293..7dc3ad73 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "php": "^8.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.0", + "friendsofphp/php-cs-fixer": "^3.68" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 29cf9391..30ce16f6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,74 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a40f40801cc414111c75ed0aa2a56c4a", + "content-hash": "f7e021131a30160aaf3ddfd798dc6633", "packages": [ - { - "name": "clue/stream-filter", - "version": "v1.7.0", - "source": { - "type": "git", - "url": "https://github.com/clue/stream-filter.git", - "reference": "049509fef80032cb3f051595029ab75b49a3c2f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/clue/stream-filter/zipball/049509fef80032cb3f051595029ab75b49a3c2f7", - "reference": "049509fef80032cb3f051595029ab75b49a3c2f7", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" - }, - "type": "library", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "Clue\\StreamFilter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christian Lück", - "email": "christian@clue.engineering" - } - ], - "description": "A simple and modern approach to stream filtering in PHP", - "homepage": "https://github.com/clue/stream-filter", - "keywords": [ - "bucket brigade", - "callback", - "filter", - "php_user_filter", - "stream", - "stream_filter_append", - "stream_filter_register" - ], - "support": { - "issues": "https://github.com/clue/stream-filter/issues", - "source": "https://github.com/clue/stream-filter/tree/v1.7.0" - }, - "funding": [ - { - "url": "https://clue.engineering/support", - "type": "custom" - }, - { - "url": "https://github.com/clue", - "type": "github" - } - ], - "time": "2023-12-20T15:40:13+00:00" - }, { "name": "guzzlehttp/guzzle", "version": "7.9.2", @@ -397,287 +331,6 @@ ], "time": "2024-07-18T11:15:46+00:00" }, - { - "name": "laudis/neo4j-php-client", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/neo4j-php/neo4j-php-client.git", - "reference": "749247655fe50a24b04a66d7df0d62a848ae159a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/neo4j-php/neo4j-php-client/zipball/749247655fe50a24b04a66d7df0d62a848ae159a", - "reference": "749247655fe50a24b04a66d7df0d62a848ae159a", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "laudis/typed-enum": "^1.3.2", - "php": "^8.1", - "php-http/discovery": "^1.13", - "php-http/message": "^1.0", - "psr/http-client": "^1.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.0|^2.0", - "psr/simple-cache": ">=2.0", - "stefanak-michal/bolt": "^7.1.4", - "symfony/polyfill-php80": "^1.2" - }, - "provide": { - "psr/simple-cache-implementation": "2.0|3.0" - }, - "require-dev": { - "cache/integration-tests": "dev-master", - "friendsofphp/php-cs-fixer": "3.15.0", - "kriswallsmith/buzz": "^1.2", - "kubawerlos/php-cs-fixer-custom-fixers": "3.13.*", - "monolog/monolog": "^2.2", - "nyholm/psr7": "^1.3", - "nyholm/psr7-server": "^1.0", - "phpunit/phpunit": "^10.0", - "psalm/plugin-phpunit": "^0.18", - "psr/log": "^3.0", - "rector/rector": "^1.0", - "symfony/uid": "^5.0", - "symfony/var-dumper": "^5.0", - "vimeo/psalm": "^5.0" - }, - "suggest": { - "composer-runtime-api": "Install composer 2 for auto detection of version in user agent", - "ext-bcmath": "Needed to implement bolt protocol", - "ext-sysvsem": "Needed for enabling connection pooling between processes", - "psr/log": "Needed to enable logging" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laudis\\Neo4j\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ghlen Nagels", - "email": "ghlen@pm.me" - } - ], - "description": "Neo4j-PHP-Client is the most advanced PHP Client for Neo4j", - "keywords": [ - "bolt", - "client", - "cluster", - "database", - "driver", - "graph", - "high-availability", - "http", - "neo4j" - ], - "support": { - "issues": "https://github.com/neo4j-php/neo4j-php-client/issues", - "source": "https://github.com/neo4j-php/neo4j-php-client/tree/3.2.0" - }, - "time": "2024-11-29T08:01:56+00:00" - }, - { - "name": "laudis/typed-enum", - "version": "1.3.2", - "source": { - "type": "git", - "url": "https://github.com/transistive/typed-enum.git", - "reference": "65cddd2ed0eedd1ff642d1ef632745ab2522c976" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/transistive/typed-enum/zipball/65cddd2ed0eedd1ff642d1ef632745ab2522c976", - "reference": "65cddd2ed0eedd1ff642d1ef632745ab2522c976", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.3", - "phpunit/phpunit": "9.*", - "psalm/plugin-phpunit": "^0.16", - "vimeo/psalm": "^4.12" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laudis\\TypedEnum\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ghlen Nagels", - "email": "ghlen@pm.me" - } - ], - "description": "A small class allowing for typed enumerations.", - "support": { - "issues": "https://github.com/transistive/typed-enum/issues", - "source": "https://github.com/transistive/typed-enum/tree/1.3.2" - }, - "time": "2022-01-04T23:33:30+00:00" - }, - { - "name": "php-http/discovery", - "version": "1.20.0", - "source": { - "type": "git", - "url": "https://github.com/php-http/discovery.git", - "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d", - "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0|^2.0", - "php": "^7.1 || ^8.0" - }, - "conflict": { - "nyholm/psr7": "<1.0", - "zendframework/zend-diactoros": "*" - }, - "provide": { - "php-http/async-client-implementation": "*", - "php-http/client-implementation": "*", - "psr/http-client-implementation": "*", - "psr/http-factory-implementation": "*", - "psr/http-message-implementation": "*" - }, - "require-dev": { - "composer/composer": "^1.0.2|^2.0", - "graham-campbell/phpspec-skip-example-extension": "^5.0", - "php-http/httplug": "^1.0 || ^2.0", - "php-http/message-factory": "^1.0", - "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", - "sebastian/comparator": "^3.0.5 || ^4.0.8", - "symfony/phpunit-bridge": "^6.4.4 || ^7.0.1" - }, - "type": "composer-plugin", - "extra": { - "class": "Http\\Discovery\\Composer\\Plugin", - "plugin-optional": true - }, - "autoload": { - "psr-4": { - "Http\\Discovery\\": "src/" - }, - "exclude-from-classmap": [ - "src/Composer/Plugin.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - } - ], - "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", - "homepage": "http://php-http.org", - "keywords": [ - "adapter", - "client", - "discovery", - "factory", - "http", - "message", - "psr17", - "psr7" - ], - "support": { - "issues": "https://github.com/php-http/discovery/issues", - "source": "https://github.com/php-http/discovery/tree/1.20.0" - }, - "time": "2024-10-02T11:20:13+00:00" - }, - { - "name": "php-http/message", - "version": "1.16.2", - "source": { - "type": "git", - "url": "https://github.com/php-http/message.git", - "reference": "06dd5e8562f84e641bf929bfe699ee0f5ce8080a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/message/zipball/06dd5e8562f84e641bf929bfe699ee0f5ce8080a", - "reference": "06dd5e8562f84e641bf929bfe699ee0f5ce8080a", - "shasum": "" - }, - "require": { - "clue/stream-filter": "^1.5", - "php": "^7.2 || ^8.0", - "psr/http-message": "^1.1 || ^2.0" - }, - "provide": { - "php-http/message-factory-implementation": "1.0" - }, - "require-dev": { - "ergebnis/composer-normalize": "^2.6", - "ext-zlib": "*", - "guzzlehttp/psr7": "^1.0 || ^2.0", - "laminas/laminas-diactoros": "^2.0 || ^3.0", - "php-http/message-factory": "^1.0.2", - "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", - "slim/slim": "^3.0" - }, - "suggest": { - "ext-zlib": "Used with compressor/decompressor streams", - "guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories", - "laminas/laminas-diactoros": "Used with Diactoros Factories", - "slim/slim": "Used with Slim Framework PSR-7 implementation" - }, - "type": "library", - "autoload": { - "files": [ - "src/filters.php" - ], - "psr-4": { - "Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - } - ], - "description": "HTTP Message related tools", - "homepage": "http://php-http.org", - "keywords": [ - "http", - "message", - "psr-7" - ], - "support": { - "issues": "https://github.com/php-http/message/issues", - "source": "https://github.com/php-http/message/tree/1.16.2" - }, - "time": "2024-10-02T11:34:13+00:00" - }, { "name": "psr/http-client", "version": "1.0.3", @@ -838,57 +491,6 @@ }, "time": "2023-04-04T09:54:51+00:00" }, - { - "name": "psr/simple-cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" - }, - "time": "2021-10-29T13:26:27+00:00" - }, { "name": "ralouphie/getallheaders", "version": "3.0.3", @@ -934,97 +536,30 @@ "time": "2019-03-08T08:55:37+00:00" }, { - "name": "stefanak-michal/bolt", - "version": "v7.1.6", + "name": "symfony/deprecation-contracts", + "version": "v3.5.1", "source": { "type": "git", - "url": "https://github.com/neo4j-php/Bolt.git", - "reference": "0c229b6c0094a91a0ad1467911353d048978fdf9" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/neo4j-php/Bolt/zipball/0c229b6c0094a91a0ad1467911353d048978fdf9", - "reference": "0c229b6c0094a91a0ad1467911353d048978fdf9", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { - "ext-curl": "*", - "ext-mbstring": "*", - "php": "^8.1", - "psr/simple-cache": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^9" - }, - "suggest": { - "ext-openssl": "Needed when using StreamSocket connection class with SSL", - "ext-sockets": "Needed when using Socket connection class", - "laudis/neo4j-php-client": "Neo4j-PHP-Client is the most advanced PHP Client for Neo4j", - "stefanak-michal/neo4j-bolt-wrapper": "Wrapper for Neo4j PHP Bolt library to simplify usage." + "php": ">=8.1" }, "type": "library", - "autoload": { - "psr-4": { - "Bolt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michal Stefanak", - "homepage": "https://www.linkedin.com/in/michalstefanak/", - "role": "Developer" - } - ], - "description": "PHP library to provide connectivity to graph database over TCP socket with Bolt specification", - "homepage": "https://github.com/neo4j-php/Bolt", - "keywords": [ - "Socket", - "bolt", - "database", - "neo4j" - ], - "support": { - "docs": "https://www.neo4j.com/docs/bolt/current/", - "issues": "https://github.com/neo4j-php/Bolt/issues", - "source": "https://github.com/neo4j-php/Bolt" - }, - "funding": [ - { - "url": "https://ko-fi.com/michalstefanak", - "type": "ko-fi" - } - ], - "time": "2024-12-03T19:05:38+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.5.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" } }, "autoload": { @@ -1066,41 +601,36 @@ } ], "time": "2024-09-25T14:20:29+00:00" - }, + } + ], + "packages-dev": [ { - "name": "symfony/polyfill-php80", - "version": "v1.31.0", + "name": "clue/ndjson-react", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=5.3", + "react/stream": "^1.2" }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" }, + "type": "library", "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] + "Clue\\React\\NDJson\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1108,516 +638,570 @@ ], "authors": [ { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Christian Lück", + "email": "christian@clue.engineering" } ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://clue.engineering/support", "type": "custom" }, { - "url": "https://github.com/fabpot", + "url": "https://github.com/clue", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" - } - ], - "packages-dev": [ + "time": "2022-12-23T10:58:28+00:00" + }, { - "name": "myclabs/deep-copy", - "version": "1.12.1", + "name": "composer/pcre", + "version": "3.3.2", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^7.4 || ^8.0" }, "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3 <3.2.2" + "phpstan/phpstan": "<1.11.10" }, "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpspec/prophecy": "^1.10", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" }, "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], "psr-4": { - "DeepCopy\\": "src/DeepCopy/" + "Composer\\Pcre\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "PCRE", + "preg", + "regex", + "regular expression" ], "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" }, "funding": [ { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], - "time": "2024-11-08T17:47:46+00:00" + "time": "2024-11-12T16:29:46+00:00" }, { - "name": "nikic/php-parser", - "version": "v5.3.1", + "name": "composer/semver", + "version": "3.4.3", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", - "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" + "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^9.0" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, - "bin": [ - "bin/php-parse" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "3.x-dev" } }, "autoload": { "psr-4": { - "PhpParser\\": "lib/PhpParser" + "Composer\\Semver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], - "description": "A PHP parser written in PHP", + "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ - "parser", - "php" + "semantic", + "semver", + "validation", + "versioning" ], "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" }, - "time": "2024-10-08T18:51:32+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-09-19T14:15:21+00:00" }, { - "name": "phar-io/manifest", - "version": "2.0.4", + "name": "composer/xdebug-handler", + "version": "3.0.5", "source": { "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "54750ef60c58e43759730615a392c31c80e23176" + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", - "reference": "54750ef60c58e43759730615a392c31c80e23176", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, + "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" } ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.4" + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" }, "funding": [ { - "url": "https://github.com/theseer", + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" } ], - "time": "2024-03-03T12:33:53+00:00" + "time": "2024-05-06T16:37:16+00:00" }, { - "name": "phar-io/version", - "version": "3.2.1", + "name": "evenement/evenement", + "version": "v3.0.2", "source": { "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9 || ^6" }, "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Evenement\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" } ], - "description": "Library for handling version information and constraints", + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" }, - "time": "2022-02-21T01:04:05+00:00" + "time": "2023-08-08T05:53:35+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "11.0.8", + "name": "fidry/cpu-core-counter", + "version": "1.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "418c59fd080954f8c4aa5631d9502ecda2387118" + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/418c59fd080954f8c4aa5631d9502ecda2387118", - "reference": "418c59fd080954f8c4aa5631d9502ecda2387118", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^5.3.1", - "php": ">=8.2", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-text-template": "^4.0.1", - "sebastian/code-unit-reverse-lookup": "^4.0.1", - "sebastian/complexity": "^4.0.1", - "sebastian/environment": "^7.2.0", - "sebastian/lines-of-code": "^3.0.1", - "sebastian/version": "^5.0.2", - "theseer/tokenizer": "^1.2.3" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^11.5.0" - }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "11.0.x-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "description": "Tiny utility to get the number of CPU cores.", "keywords": [ - "coverage", - "testing", - "xunit" + "CPU", + "core" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.8" + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/theofidry", "type": "github" } ], - "time": "2024-12-11T12:34:27+00:00" + "time": "2024-08-06T10:04:20+00:00" }, { - "name": "phpunit/php-file-iterator", - "version": "5.1.0", + "name": "friendsofphp/php-cs-fixer", + "version": "v3.68.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c", + "reference": "73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c", "shasum": "" }, "require": { - "php": ">=8.2" + "clue/ndjson-react": "^1.0", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.2", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.5", + "react/event-loop": "^1.0", + "react/promise": "^2.0 || ^3.0", + "react/socket": "^1.0", + "react/stream": "^1.0", + "sebastian/diff": "^4.0 || ^5.1 || ^6.0", + "symfony/console": "^5.4 || ^6.4 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", + "symfony/finder": "^5.4 || ^6.4 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.4 || ^7.0", + "symfony/polyfill-mbstring": "^1.31", + "symfony/polyfill-php80": "^1.31", + "symfony/polyfill-php81": "^1.31", + "symfony/process": "^5.4 || ^6.4 || ^7.2", + "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "facile-it/paraunit": "^1.3.1 || ^2.4", + "infection/infection": "^0.29.8", + "justinrainbow/json-schema": "^5.3 || ^6.0", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.7", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", + "phpunit/phpunit": "^9.6.22 || ^10.5.40 || ^11.5.2", + "symfony/var-dumper": "^5.4.48 || ^6.4.15 || ^7.2.0", + "symfony/yaml": "^5.4.45 || ^6.4.13 || ^7.2.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", "autoload": { - "classmap": [ - "src/" + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" ] }, "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": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" } ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "description": "A tool to automatically fix PHP code style", "keywords": [ - "filesystem", - "iterator" + "Static code analysis", + "fixer", + "standards", + "static analysis" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.68.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/keradus", "type": "github" } ], - "time": "2024-08-27T05:02:59+00:00" + "time": "2025-01-13T17:01:01+00:00" }, { - "name": "phpunit/php-invoker", - "version": "5.0.1", + "name": "myclabs/deep-copy", + "version": "1.12.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { - "php": ">=8.2" + "php": "^7.1 || ^8.0" }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^11.0" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, - "suggest": { - "ext-pcntl": "*" + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } + "MIT" ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "description": "Create deep copies (clones) of your objects", "keywords": [ - "process" + "clone", + "copy", + "duplicate", + "object", + "object graph" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" } ], - "time": "2024-07-03T05:07:44+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { - "name": "phpunit/php-text-template", - "version": "4.0.1", + "name": "nikic/php-parser", + "version": "v5.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", "shasum": "" }, "require": { - "php": ">=8.2" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1625,53 +1209,46 @@ ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nikita Popov" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "A PHP parser written in PHP", "keywords": [ - "template" + "parser", + "php" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:08:43+00:00" + "time": "2024-12-30T11:07:19+00:00" }, { - "name": "phpunit/php-timer", - "version": "7.0.1", + "name": "phar-io/manifest", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "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-main": "7.0-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1684,88 +1261,129 @@ "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": "lead" + "role": "Developer" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/theseer", "type": "github" } ], - "time": "2024-07-03T05:09:35+00:00" + "time": "2024-03-03T12:33:53+00:00" }, { - "name": "phpunit/phpunit", - "version": "11.5.2", + "name": "phar-io/version", + "version": "3.2.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "153d0531b9f7e883c5053160cad6dd5ac28140b3" + "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": "11.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "418c59fd080954f8c4aa5631d9502ecda2387118" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/153d0531b9f7e883c5053160cad6dd5ac28140b3", - "reference": "153d0531b9f7e883c5053160cad6dd5ac28140b3", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/418c59fd080954f8c4aa5631d9502ecda2387118", + "reference": "418c59fd080954f8c4aa5631d9502ecda2387118", "shasum": "" }, "require": { "ext-dom": "*", - "ext-json": "*", "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.1", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", + "nikic/php-parser": "^5.3.1", "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.8", "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-invoker": "^5.0.1", "phpunit/php-text-template": "^4.0.1", - "phpunit/php-timer": "^7.0.1", - "sebastian/cli-parser": "^3.0.2", - "sebastian/code-unit": "^3.0.2", - "sebastian/comparator": "^6.2.1", - "sebastian/diff": "^6.0.2", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", "sebastian/environment": "^7.2.0", - "sebastian/exporter": "^6.3.0", - "sebastian/global-state": "^7.0.2", - "sebastian/object-enumerator": "^6.0.1", - "sebastian/type": "^5.1.0", + "sebastian/lines-of-code": "^3.0.1", "sebastian/version": "^5.0.2", - "staabm/side-effects-detector": "^1.0.5" + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^11.5.0" }, "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, - "bin": [ - "phpunit" - ], "type": "library", "extra": { "branch-alias": { - "dev-main": "11.5-dev" + "dev-main": "11.0.x-dev" } }, "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], "classmap": [ "src/" ] @@ -1781,46 +1399,38 @@ "role": "lead" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://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": [ - "phpunit", + "coverage", "testing", "xunit" ], "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.2" + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.8" }, "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" } ], - "time": "2024-12-21T05:51:08+00:00" + "time": "2024-12-11T12:34:27+00:00" }, { - "name": "sebastian/cli-parser", - "version": "3.0.2", + "name": "phpunit/php-file-iterator", + "version": "5.1.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", "shasum": "" }, "require": { @@ -1832,7 +1442,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1851,12 +1461,16 @@ "role": "lead" } ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", + "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/cli-parser/issues", - "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" }, "funding": [ { @@ -1864,32 +1478,36 @@ "type": "github" } ], - "time": "2024-07-03T04:41:36+00:00" + "time": "2024-08-27T05:02:59+00:00" }, { - "name": "sebastian/code-unit", - "version": "3.0.2", + "name": "phpunit/php-invoker", + "version": "5.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", - "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.5" + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1908,12 +1526,15 @@ "role": "lead" } ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.2" + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" }, "funding": [ { @@ -1921,20 +1542,20 @@ "type": "github" } ], - "time": "2024-12-12T09:59:06+00:00" + "time": "2024-07-03T05:07:44+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", + "name": "phpunit/php-text-template", "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", "shasum": "" }, "require": { @@ -1961,15 +1582,19 @@ "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/", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" }, "funding": [ { @@ -1977,36 +1602,32 @@ "type": "github" } ], - "time": "2024-07-03T04:45:54+00:00" + "time": "2024-07-03T05:08:43+00:00" }, { - "name": "sebastian/comparator", - "version": "6.2.1", + "name": "phpunit/php-timer", + "version": "7.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/43d129d6a0f81c78bee378b46688293eb7ea3739", - "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/diff": "^6.0", - "sebastian/exporter": "^6.0" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.4" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.2-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2021,32 +1642,19 @@ "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" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ - "comparator", - "compare", - "equality" + "timer" ], "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.2.1" + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" }, "funding": [ { @@ -2054,36 +1662,66 @@ "type": "github" } ], - "time": "2024-10-31T05:30:08+00:00" + "time": "2024-07-03T05:09:35+00:00" }, { - "name": "sebastian/complexity", - "version": "4.0.1", + "name": "phpunit/phpunit", + "version": "11.5.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "30e319e578a7b5da3543073e30002bf82042f701" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/30e319e578a7b5da3543073e30002bf82042f701", + "reference": "30e319e578a7b5da3543073e30002bf82042f701", "shasum": "" }, "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.12.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.8", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.2", + "sebastian/comparator": "^6.3.0", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.3.0", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" }, + "bin": [ + "phpunit" + ], "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "11.5-dev" } }, "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], "classmap": [ "src/" ] @@ -2099,690 +1737,2903 @@ "role": "lead" } ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.3" }, "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" } ], - "time": "2024-07-03T04:49:50+00:00" + "time": "2025-01-13T09:36:00+00:00" }, { - "name": "sebastian/diff", - "version": "6.0.2", + "name": "psr/container", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0", - "symfony/process": "^4.2 || ^5" + "php": ">=7.4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Psr\\Container\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" ], "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:53:05+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { - "name": "sebastian/environment", - "version": "7.2.0", + "name": "psr/event-dispatcher", + "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "suggest": { - "ext-posix": "*" + "php": ">=7.2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.2-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "https://github.com/sebastianbergmann/environment", + "description": "Standard interfaces for event handling.", "keywords": [ - "Xdebug", - "environment", - "hhvm" + "events", + "psr", + "psr-14" ], "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:54:44+00:00" + "time": "2019-01-08T18:20:26+00:00" }, { - "name": "sebastian/exporter", - "version": "6.3.0", + "name": "psr/log", + "version": "3.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3" + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/3473f61172093b2da7de1fb5782e1f24cc036dc3", - "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/recursion-context": "^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-master": "3.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Psr\\Log\\": "src" + } }, "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": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ - "export", - "exporter" + "log", + "psr", + "psr-3" ], "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.0" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-12-05T09:17:50+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { - "name": "sebastian/global-state", - "version": "7.0.2", + "name": "react/cache", + "version": "v1.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", "shasum": "" }, "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" }, "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "React\\Cache\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", + "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.6", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", + "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.6" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-01-01T16:37:48+00:00" + }, + { + "name": "react/dns", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.13.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-13T14:18:03+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/promise", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.10.39 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-05-24T10:39:05+00:00" + }, + { + "name": "react/socket", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.16.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-07-26T10:38:09+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-12-12T09:59:06+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:45:54+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/d4e47a769525c4dd38cea90e5dcd435ddbbc7115", + "reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-01-06T10:28:19+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:54:44+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/3473f61172093b2da7de1fb5782e1f24cc036dc3", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-12-05T09:17:50+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ - "global state" + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "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", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:00:13+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:01:32+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:10:34+00:00" + }, + { + "name": "sebastian/type", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "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", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-09-17T13:12:04+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T05:16:32+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" + }, + { + "name": "symfony/console", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "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": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-11T03:49:26+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides 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/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", + "shasum": "" + }, + "require": { + "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.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-25T15:15:23+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "87a71856f2f56e4100373e92529eed3171695cfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", + "reference": "87a71856f2f56e4100373e92529eed3171695cfb", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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": { + "source": "https://github.com/symfony/finder/tree/v7.2.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-30T19:00:17+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-20T11:17:29+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" ], "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:57:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/lines-of-code", - "version": "3.0.1", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" + "php": ">=7.2" }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "suggest": { + "ext-intl": "For best performance" }, "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\\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", - "role": "lead" + "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 for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T04:58:38+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "6.0.1", + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" + "php": ">=7.2" }, - "require-dev": { - "phpunit/phpunit": "^11.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": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "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" + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "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.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T05:00:13+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/object-reflector", - "version": "4.0.1", + "name": "symfony/polyfill-php81", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "4.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\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": "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.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T05:01:32+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/recursion-context", - "version": "6.0.2", + "name": "symfony/process", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + "url": "https://github.com/symfony/process.git", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", "shasum": "" }, "require": { "php": ">=8.2" }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" + "source": "https://github.com/symfony/process/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-07-03T05:10:34+00:00" + "time": "2024-11-06T14:24:19+00:00" }, { - "name": "sebastian/type", - "version": "5.1.0", + "name": "symfony/service-contracts", + "version": "v3.5.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", - "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, - "require-dev": { - "phpunit/phpunit": "^11.3" + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "3.5-dev" } }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-09-17T13:12:04+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { - "name": "sebastian/version", - "version": "5.0.2", + "name": "symfony/stopwatch", + "version": "v7.2.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + "url": "https://github.com/symfony/stopwatch.git", + "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e46690d5b9d7164a6d061cab1e8d46141b9f49df", + "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" + "source": "https://github.com/symfony/stopwatch/tree/v7.2.2" }, "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-10-09T05:16:32+00:00" + "time": "2024-12-18T14:28:33+00:00" }, { - "name": "staabm/side-effects-detector", - "version": "1.0.5", + "name": "symfony/string", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/staabm/side-effects-detector.git", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + "url": "https://github.com/symfony/string.git", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": "^7.4 || ^8.0" + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.6", - "phpunit/phpunit": "^9.6.21", - "symfony/var-dumper": "^5.4.43", - "tomasvotruba/type-coverage": "1.0.0", - "tomasvotruba/unused-public": "1.0.0" + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", "autoload": { - "classmap": [ - "lib/" + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "A static analysis tool to detect side effects in PHP code", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", "keywords": [ - "static analysis" + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" ], "support": { - "issues": "https://github.com/staabm/side-effects-detector/issues", - "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/staabm", + "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-10-20T05:08:20+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "theseer/tokenizer", @@ -2837,13 +4688,13 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { "ext-json": "*", "php": "^8.1" }, - "platform-dev": {}, + "platform-dev": [], "plugin-api-version": "2.6.0" } diff --git a/src/Neo4jQueryAPI.php b/src/Neo4jQueryAPI.php index 71198a84..e0ddc80e 100644 --- a/src/Neo4jQueryAPI.php +++ b/src/Neo4jQueryAPI.php @@ -59,15 +59,21 @@ public function run(string $cypher, array $parameters = [], string $database = ' $payload['bookmarks'] = $bookmark->getBookmarks(); } - $response = $this->client->post('/db/' . $database . '/query/v2', [ + $response = $this->client->request('POST', '/db/' . $database . '/query/v2', [ 'json' => $payload, ]); - $data = json_decode($response->getBody()->getContents(), true); + $contents = $response->getBody()->getContents(); + $data = json_decode($contents, true, flags: JSON_THROW_ON_ERROR); $ogm = new OGM(); - $keys = $data['data']['fields']; - $values = $data['data']['values']; + $keys = $data['data']['fields'] ?? []; + $values = $data['data']['values'] ?? []; // Ensure $values is an array + + if (!is_array($values)) { + throw new RuntimeException('Unexpected response format: values is not an array.'); + } + $rows = array_map(function ($resultRow) use ($ogm, $keys) { $data = []; foreach ($keys as $index => $key) { @@ -76,7 +82,6 @@ public function run(string $cypher, array $parameters = [], string $database = ' } return new ResultRow($data); }, $values); - $profile = isset($data['profiledQueryPlan']) ? $this->createProfileData($data['profiledQueryPlan']) : null; $resultCounters = new ResultCounters( @@ -132,28 +137,34 @@ private function createProfileData(array $data): ProfiledQueryPlan $arguments = $data['arguments']; $mappedArguments = []; foreach ($arguments as $key => $value) { - $mappedArguments[$key] = $ogm->map($value); + if (is_array($value) && array_key_exists('$type', $value) && array_key_exists('_value', $value)) { + $mappedArguments[$key] = $ogm->map($value); + } else { + $mappedArguments[$key] = $value; + } } $queryArguments = new ProfiledQueryPlanArguments( - $mappedArguments['globalMemory'], - $mappedArguments['plannerImpl'], + $mappedArguments['GlobalMemory'], + $mappedArguments['planner-impl'], $mappedArguments['memory'], - $mappedArguments['stringRepresentation'], - is_string($mappedArguments['runtime'] ? $mappedArguments['runtime'] : json_encode($mappedArguments['runtime'])), - $mappedArguments['time'], - $mappedArguments['pageCacheMisses'], - $mappedArguments['runtimeImpl'], - $mappedArguments['dbHits'], - $mappedArguments['batchSize'], - $mappedArguments['details'], - $mappedArguments['plannerVersion'], - $mappedArguments['pipelineInfo'], - $mappedArguments['runtimeVersion'], - $mappedArguments['id'], - (float)($mappedArguments['estimatedRows'] ?? 0.0), + $mappedArguments['string-representation'], + $mappedArguments['runtime'] ?? null, + $mappedArguments['Time'], + is_int($mappedArguments['PageCacheMisses']), + is_int($mappedArguments['PageCacheHits']), + $mappedArguments['runtime-impl'], + $mappedArguments['version'], + is_int($mappedArguments['DbHits']), + $mappedArguments['batch-size'], + is_string($mappedArguments['Details']), + $mappedArguments['planner-version'], + is_string($mappedArguments['PipelineInfo']), + $mappedArguments['runtime-version'], + is_int($mappedArguments['Id']), + (float)($mappedArguments['EstimatedRows'] ?? 0.0), is_string($mappedArguments['planner'] ? $mappedArguments['planner'] : json_encode($mappedArguments['planner'])), - $mappedArguments['rows'] + is_int($mappedArguments['Rows']) ); @@ -161,7 +172,7 @@ private function createProfileData(array $data): ProfiledQueryPlan $data['dbHits'], $data['records'], $data['hasPageCacheStats'], - $data['pageCacheHits'], + $data['PageCacheHits'], $data['pageCacheMisses'], $data['pageCacheHitRatio'], $data['time'], diff --git a/src/Objects/ProfiledQueryPlanArguments.php b/src/Objects/ProfiledQueryPlanArguments.php index e61a7c37..3329ba85 100644 --- a/src/Objects/ProfiledQueryPlanArguments.php +++ b/src/Objects/ProfiledQueryPlanArguments.php @@ -14,6 +14,7 @@ public function __construct( private readonly ?int $pageCacheMisses = null, private readonly ?int $pageCacheHits = null, private readonly ?string $runtimeImpl = null, + private readonly ?int $version = null, private readonly ?int $dbHits = null, private readonly ?int $batchSize = null, private readonly ?string $details = null, @@ -70,6 +71,10 @@ public function getRuntimeImpl(): string { return $this->runtimeImpl; } + public function getVersion(): string + { + return $this->version; + } public function getDbHits(): int { diff --git a/tests/Integration/Neo4jQueryAPIIntegrationTest.php b/tests/Integration/Neo4jQueryAPIIntegrationTest.php index e4944752..fe558211 100644 --- a/tests/Integration/Neo4jQueryAPIIntegrationTest.php +++ b/tests/Integration/Neo4jQueryAPIIntegrationTest.php @@ -17,6 +17,7 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Neo4j\QueryAPI\Transaction; +use Psr\Http\Client\RequestExceptionInterface; class Neo4jQueryAPIIntegrationTest extends TestCase { @@ -158,18 +159,23 @@ public function testProfileCreateWatchedWithFilters(): void $this->assertNotNull($result->getProfiledQueryPlan(), "profiled query plan not found"); } - public function testProfileCreateKnowsBidirectionalRelationshipsMock(): void + /** + * @throws Neo4jException + * @throws RequestExceptionInterface + */ + public function testProfileCreateKnowsBidirectionalRelationshipsMock(): void { $query = " - PROFILE UNWIND range(1, 100) AS i - UNWIND range(1, 100) AS j - MATCH (a:Person {id: i}), (b:Person {id: j}) - WHERE a.id < b.id AND rand() < 0.1 - CREATE (a)-[:KNOWS]->(b), (b)-[:KNOWS]->(a); + PROFILE UNWIND range(1, 100) AS i + UNWIND range(1, 100) AS j + MATCH (a:Person {id: i}), (b:Person {id: j}) + WHERE a.id < b.id AND rand() < 0.1 + CREATE (a)-[:KNOWS]->(b), (b)-[:KNOWS]->(a); "; + $body = file_get_contents(__DIR__ . '/../resources/responses/complex-query-profile.json'); $mockSack = new MockHandler([ - new Response(200, [], file_get_contents(__DIR__ . '/../resources/responses/complex-query-profile.json')), + new Response(200, [], $body), ]); $handler = HandlerStack::create($mockSack); @@ -177,11 +183,15 @@ public function testProfileCreateKnowsBidirectionalRelationshipsMock(): void $api = new Neo4jQueryAPI($client); $result = $api->run($query); + $plan = $result->getProfiledQueryPlan(); + $this->assertNotNull($plan, "The result of the query should not be null."); - $expected = require __DIR__.'/../resources/expected/complex-query-profile.php'; + // Load expected data + $expected = require __DIR__ . '/../resources/expected/complex-query-profile.php'; - $this->assertEquals($expected, "profiled query plan not found"); + // Assert the profiled query plan matches the expected result + $this->assertEquals($expected->getProfiledQueryPlan(), $plan, "Profiled query plan does not match the expected value."); } public function testProfileCreateActedInRelationships(): void diff --git a/tests/resources/expected/complex-query-profile.php b/tests/resources/expected/complex-query-profile.php index 5525ee40..866ea11c 100644 --- a/tests/resources/expected/complex-query-profile.php +++ b/tests/resources/expected/complex-query-profile.php @@ -1,13 +1,14 @@ (b), (b)-[anon_1:KNOWS]->(a) | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +Filter | 3 | cache[a.id] < cache[b.id] | 2 | 0 | 0 | | 0/0 | 0.000 | In Pipeline 3 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Apply | 4 | | 8 | 0 | 0 | | 0/0 | | |\n| |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +CartesianProduct | 5 | | 8 | 0 | 0 | 1392 | | | In Pipeline 3 |\n| | |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | | +Filter | 6 | cache[b.id] = j | 50 | 0 | 0 | | | | |\n| | | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | | +NodeByLabelScan | 7 | b:Person | 1000 | 0 | 0 | 256 | 0/0 | 0.000 | Fused in Pipeline 2 |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +Filter | 8 | rand() < \$autodouble_4 AND cache[a.id] = i | 15 | 0 | 2027 | | | | |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | +NodeByLabelScan | 9 | a:Person | 1000 | 20000 | 30000 | 8488 | 10002/0 | 6.158 | Fused in Pipeline 1 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Unwind | 10 | range(\$autoint_2, \$autoint_3) AS j | 100 | 10000 | 0 | | | | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| +Unwind | 11 | range(\$autoint_0, \$autoint_1) AS i | 10 | 100 | 0 | | 0/0 | 0.000 | Fused in Pipeline 0 |\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n\nTotal database accesses: 32027, total allocated memory: 10624\n" + , "PIPELINED", 0, + 1, + 1, + "PIPELINED", + 5, + 1, 128, - "", + '1', 5.26, - "In Pipeline 3", + '1', 5.26, - 0, + 1, 2.25, - "COST", - 0, + 1, + 1 ), [ new ProfiledQueryPlan( @@ -61,26 +69,28 @@ 0, "EmptyResult@neo4j", new ProfiledQueryPlanArguments( - "null", null, null, null, null, - 0, - 0, - 0, null, 0, + 1, + 1, null, null, + 1, null, - "In Pipeline 3", + '', null, - 0, - 2.25, + "1", null, - 0 + 1, + 2.25, + '1', + 1 ), + [ new ProfiledQueryPlan( 0, @@ -93,27 +103,28 @@ "Create@neo4j", new ProfiledQueryPlanArguments( null, - "In Pipeline 3", - 0, - 0, + null, + null, + null, null, 0, - 2.25, 0, 0, + null, + null, 0, null, - "(a)-[anon_0:KNOWS]->(b), (b)-[anon_1:KNOWS]->(a)", + '1', null, - "In Pipeline 3", + '1', null, - 2, + 0, 2.25, - null, + '1', 0 ) ), - [ + new ProfiledQueryPlan( 0, 0, @@ -135,6 +146,7 @@ null, 0, null, + null, "cache[a.id] < cache[b.id]", null, "In Pipeline 3", @@ -161,9 +173,10 @@ null, null, null, + null, 0, 0, - 0, + null, null, 0, null, @@ -193,15 +206,16 @@ null, null, null, - 0, - 0, - 0, + null, + null, + null, + null, null, 0, null, - "range(\$autoint_2, \$autoint_3) AS j", null, - "Fused in Pipeline 0", + null, + "range(\$autoint_2, \$autoint_3) AS j", null, 10, 100.0, @@ -229,6 +243,7 @@ 0, 0, null, + null, 0, null, "range(\$autoint_0, \$autoint_1) AS i", @@ -236,9 +251,10 @@ "Fused in Pipeline 0", null, 11, - 10.0, + null, null, 100 + ) ), [ @@ -266,6 +282,7 @@ null, null, null, + null, "In Pipeline 3", null, 5, @@ -276,62 +293,34 @@ ), [ + new ProfiledQueryPlan( - 0, + 2027, 0, false, 0, 0, 0.0, 0, - "CartesianProduct@neo4j", + "Filter@neo4j", new ProfiledQueryPlanArguments( null, null, - 1392, null, null, - 0, - 0, - 0, null, - 0, null, null, null, - "In Pipeline 3", - null, - 5, - 7.5, - null, - 0 - ) - ), - new ProfiledQueryPlan( - 2027, - 0, - false, - 0, - 0, - 0.0, - 0, - "Filter@neo4j", - new ProfiledQueryPlanArguments( - "rand() < \$autodouble_4 AND cache[a.id] = i", - "Fused in Pipeline 1", - 8, null, null, 2027, - 0, - 0, - null, - 0, - null, - null, null, + "rand() < \$autodouble_4 AND cache[a.id] = i", null, + "Fused in Pipeline 1", null, + 8, 15.0, null, 0 @@ -347,24 +336,26 @@ 6157670, "NodeByLabelScan@neo4j", new ProfiledQueryPlanArguments( - "a:Person", - "Fused in Pipeline 1", - 9, null, null, - 30000, - 20000, - 0, + 8488, null, + null, + 6157670, + 0, 10002, null, null, + 30000, null, + "a:Person", null, + "Fused in Pipeline 1", null, + 9, 1000.0, null, - 6157670 + 20000 ) ), new ProfiledQueryPlan( @@ -377,21 +368,23 @@ 0, "Filter@neo4j", new ProfiledQueryPlanArguments( - "cache[b.id] = j", + null, "Fused in Pipeline 2", 6, null, null, - 0, - 0, - 0, null, - 0, null, null, null, null, + 0, + null, + "cache[b.id] = j", + null, + "Fused in Pipeline 2", null, + 6, 50.0, null, 0 @@ -408,21 +401,23 @@ 0, "NodeByLabelScan@neo4j", new ProfiledQueryPlanArguments( - "b:Person", - "Fused in Pipeline 2", - 7, + null, + null, + 256, null, null, 0, 0, 0, null, - 0, - null, null, + 0, null, + "b:Person", null, + "Fused in Pipeline 2", null, + 7, 1000.0, null, 0 @@ -440,10 +435,11 @@ ] - ] + ] + ) ] diff --git a/tests/resources/responses/complex-query-profile.json b/tests/resources/responses/complex-query-profile.json index 43bf0e5c..9f61e414 100644 --- a/tests/resources/responses/complex-query-profile.json +++ b/tests/resources/responses/complex-query-profile.json @@ -71,16 +71,16 @@ "pageCacheHitRatio" : 0.0, "time" : 0, "operatorType" : "EmptyResult@neo4j", - "arguments" : { - "PipelineInfo" : "In Pipeline 3", - "Time" : 0, - "Id" : 1, - "PageCacheMisses" : 0, - "EstimatedRows" : 2.25, - "DbHits" : 0, - "Rows" :0, - "PageCacheHits" :0 - }, + "arguments" : { + "PipelineInfo" : "In Pipeline 3", + "Time" : 0, + "Id" : 1, + "PageCacheMisses" : 0, + "EstimatedRows" : 2.25, + "DbHits" : 0, + "Rows" :0, + "PageCacheHits" :0 + }, "identifiers" : [ "j", "a", "i", "b", "anon_0", "anon_1" ], "children" : [ { "dbHits" : 0, @@ -298,7 +298,7 @@ } }, "identifiers" : [ "i" ], - "children" : [ ] /*till here */ + "children" : [ ] } ] }, { "dbHits" : 0, From 2bf17961976c0fe2dd74bc7ce236c2b3d28a9523 Mon Sep 17 00:00:00 2001 From: Pratiksha Date: Thu, 16 Jan 2025 16:28:41 +0530 Subject: [PATCH 5/9] winp --- .../expected/complex-query-profile.php | 349 +----------------- 1 file changed, 1 insertion(+), 348 deletions(-) diff --git a/tests/resources/expected/complex-query-profile.php b/tests/resources/expected/complex-query-profile.php index 866ea11c..fda07f40 100644 --- a/tests/resources/expected/complex-query-profile.php +++ b/tests/resources/expected/complex-query-profile.php @@ -89,356 +89,9 @@ 2.25, '1', 1 - ), - - [ - new ProfiledQueryPlan( - 0, - 0, - false, - 0, - 0, - 0.0, - 0, - "Create@neo4j", - new ProfiledQueryPlanArguments( - null, - null, - null, - null, - null, - 0, - 0, - 0, - null, - null, - 0, - null, - '1', - null, - '1', - null, - 0, - 2.25, - '1', - 0 - ) - ), - - new ProfiledQueryPlan( - 0, - 0, - false, - 0, - 0, - 0.0, - 0, - "Filter@neo4j", - new ProfiledQueryPlanArguments( - null, - null, - null, - null, - null, - 0, - 0, - 0, - null, - 0, - null, - null, - "cache[a.id] < cache[b.id]", - null, - "In Pipeline 3", - null, - 3, - 2.25, - null, - 0 - ) - ), - [ - new ProfiledQueryPlan( - 0, - 0, - false, - 0, - 0, - 0.0, - 0, - "Apply@neo4j", - new ProfiledQueryPlanArguments( - null, - null, - null, - null, - null, - null, - 0, - 0, - null, - null, - 0, - null, - null, - null, - null, - null, - 4, - 7.5, - null, - 0 - ) - ), - [ - new ProfiledQueryPlan( - 0, - 10000, - false, - 0, - 0, - 0.0, - 0, - "Unwind@neo4j", - new ProfiledQueryPlanArguments( - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - 0, - null, - null, - null, - "range(\$autoint_2, \$autoint_3) AS j", - null, - 10, - 100.0, - null, - 10000 - ) - ), - [ - new ProfiledQueryPlan( - 0, - 100, - false, - 0, - 0, - 0.0, - 0, - "Unwind@neo4j", - new ProfiledQueryPlanArguments( - null, - null, - null, - null, - null, - 0, - 0, - 0, - null, - null, - 0, - null, - "range(\$autoint_0, \$autoint_1) AS i", - null, - "Fused in Pipeline 0", - null, - 11, - null, - null, - 100 - - ) - ), - [ - [ - new ProfiledQueryPlan( - 0, - 0, - false, - 0, - 0, - 0.0, - 0, - "CartesianProduct@neo4j", - new ProfiledQueryPlanArguments( - null, - null, - 1392, - null, - null, - 0, - 0, - 0, - null, - 0, - null, - null, - null, - null, - "In Pipeline 3", - null, - 5, - 7.5, - null, - 0 - ) - ), - - [ - - new ProfiledQueryPlan( - 2027, - 0, - false, - 0, - 0, - 0.0, - 0, - "Filter@neo4j", - new ProfiledQueryPlanArguments( - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - 2027, - null, - "rand() < \$autodouble_4 AND cache[a.id] = i", - null, - "Fused in Pipeline 1", - null, - 8, - 15.0, - null, - 0 - ) - ), - new ProfiledQueryPlan( - 30000, - 20000, - true, - 10002, - 0, - 1.0, - 6157670, - "NodeByLabelScan@neo4j", - new ProfiledQueryPlanArguments( - null, - null, - 8488, - null, - null, - 6157670, - 0, - 10002, - null, - null, - 30000, - null, - "a:Person", - null, - "Fused in Pipeline 1", - null, - 9, - 1000.0, - null, - 20000 - ) - ), - new ProfiledQueryPlan( - 0, - 0, - false, - 0, - 0, - 0.0, - 0, - "Filter@neo4j", - new ProfiledQueryPlanArguments( - null, - "Fused in Pipeline 2", - 6, - null, - null, - null, - null, - null, - null, - null, - 0, - null, - "cache[b.id] = j", - null, - "Fused in Pipeline 2", - null, - 6, - 50.0, - null, - 0 - ) - ), - - new ProfiledQueryPlan( - 0, - 0, - false, - 0, - 0, - 0.0, - 0, - "NodeByLabelScan@neo4j", - new ProfiledQueryPlanArguments( - null, - null, - 256, - null, - null, - 0, - 0, - 0, - null, - null, - 0, - null, - "b:Person", - null, - "Fused in Pipeline 2", - null, - 7, - 1000.0, - null, - 0 - ) - ) - - ] - - ] - - ] - ] - - ] - - ] - - + ), - ] ) ] From 122a01c54093eebc6e68743a3aba8cb5c17ad390 Mon Sep 17 00:00:00 2001 From: Pratiksha Date: Mon, 20 Jan 2025 10:37:53 +0530 Subject: [PATCH 6/9] test for Profile-query-plan working state --- .php-cs-fixer.php | 18 + src/Neo4jQueryAPI.php | 44 +- .../expected/complex-query-profile.php | 482 +++++++++++++++--- .../responses/complex-query-profile.json | 3 +- 4 files changed, 441 insertions(+), 106 deletions(-) create mode 100644 .php-cs-fixer.php diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 00000000..28bf20e3 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,18 @@ +setRiskyAllowed(true) // Allow risky fixers + ->setRules([ + '@PSR12' => true, + 'strict_param' => true, // This is a risky rule + ]) + ->setFinder( + Finder::create() + ->in(__DIR__) + ->exclude([ + 'vendor', + ]) + ); diff --git a/src/Neo4jQueryAPI.php b/src/Neo4jQueryAPI.php index e0ddc80e..6aa2f18b 100644 --- a/src/Neo4jQueryAPI.php +++ b/src/Neo4jQueryAPI.php @@ -4,8 +4,6 @@ use Exception; use GuzzleHttp\Client; -use GuzzleHttp\Exception\GuzzleException; -use GuzzleHttp\Exception\RequestException; use Neo4j\QueryAPI\Objects\ProfiledQueryPlanArguments; use Neo4j\QueryAPI\Objects\ResultCounters; use Neo4j\QueryAPI\Objects\ProfiledQueryPlan; @@ -145,26 +143,26 @@ private function createProfileData(array $data): ProfiledQueryPlan } $queryArguments = new ProfiledQueryPlanArguments( - $mappedArguments['GlobalMemory'], - $mappedArguments['planner-impl'], - $mappedArguments['memory'], - $mappedArguments['string-representation'], - $mappedArguments['runtime'] ?? null, - $mappedArguments['Time'], - is_int($mappedArguments['PageCacheMisses']), - is_int($mappedArguments['PageCacheHits']), - $mappedArguments['runtime-impl'], - $mappedArguments['version'], - is_int($mappedArguments['DbHits']), - $mappedArguments['batch-size'], - is_string($mappedArguments['Details']), - $mappedArguments['planner-version'], - is_string($mappedArguments['PipelineInfo']), - $mappedArguments['runtime-version'], - is_int($mappedArguments['Id']), - (float)($mappedArguments['EstimatedRows'] ?? 0.0), - is_string($mappedArguments['planner'] ? $mappedArguments['planner'] : json_encode($mappedArguments['planner'])), - is_int($mappedArguments['Rows']) + globalMemory: $mappedArguments['GlobalMemory'] ?? null, + plannerImpl: $mappedArguments['planner-impl'] ?? null, + memory: $mappedArguments['Memory'] ?? null, + stringRepresentation: $mappedArguments['string-representation'] ?? null, + runtime: $mappedArguments['runtime'] ?? null, + time: $mappedArguments['Time'] ?? null, + pageCacheMisses: $mappedArguments['PageCacheMisses'] ?? null, + pageCacheHits: $mappedArguments['PageCacheHits'] ?? null, + runtimeImpl: $mappedArguments['runtime-impl'] ?? null, + version: $mappedArguments['version'] ?? null, + dbHits: $mappedArguments['DbHits'] ?? null, + batchSize: $mappedArguments['batch-size'] ?? null, + details: $mappedArguments['Details'] ?? null, + plannerVersion: $mappedArguments['planner-version'] ?? null, + pipelineInfo: $mappedArguments['PipelineInfo'] ?? null, + runtimeVersion: $mappedArguments['runtime-version'] ?? null, + id: $mappedArguments['Id'] ?? null, + estimatedRows: $mappedArguments['EstimatedRows'] ?? null, + planner: $mappedArguments['planner'] ?? null, + rows: $mappedArguments['Rows' ?? null] ); @@ -172,7 +170,7 @@ private function createProfileData(array $data): ProfiledQueryPlan $data['dbHits'], $data['records'], $data['hasPageCacheStats'], - $data['PageCacheHits'], + $data['pageCacheHits'], $data['pageCacheMisses'], $data['pageCacheHitRatio'], $data['time'], diff --git a/tests/resources/expected/complex-query-profile.php b/tests/resources/expected/complex-query-profile.php index fda07f40..4ab3e442 100644 --- a/tests/resources/expected/complex-query-profile.php +++ b/tests/resources/expected/complex-query-profile.php @@ -9,94 +9,412 @@ return new ResultSet( rows: [], counters: new ResultCounters( - false, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - false, - 0 + containsUpdates: false, + nodesCreated: 0, + nodesDeleted: 0, + propertiesSet: 0, + relationshipsCreated: 0, + relationshipsDeleted: 0, + labelsAdded: 0, + labelsRemoved: 0, + indexesAdded: 0, + indexesRemoved: 0, + constraintsAdded: 0, + constraintsRemoved: 0, + containsSystemUpdates: false, + systemUpdates: 0 ), bookmarks: new Bookmarks([]), profiledQueryPlan: new ProfiledQueryPlan( - 0, - 0, - false, - 0, - 0, - 0.0, - 0, - "ProduceResults@neo4j", - - new ProfiledQueryPlanArguments( - 10624, - "IDP", - null, - "Cypher 5\n\nPlanner COST\n\nRuntime PIPELINED\n\nRuntime version 5.26\n\nBatch size 128\n\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline |\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +ProduceResults | 0 | | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +EmptyResult | 1 | | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +Create | 2 | (a)-[anon_0:KNOWS]->(b), (b)-[anon_1:KNOWS]->(a) | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +Filter | 3 | cache[a.id] < cache[b.id] | 2 | 0 | 0 | | 0/0 | 0.000 | In Pipeline 3 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Apply | 4 | | 8 | 0 | 0 | | 0/0 | | |\n| |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +CartesianProduct | 5 | | 8 | 0 | 0 | 1392 | | | In Pipeline 3 |\n| | |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | | +Filter | 6 | cache[b.id] = j | 50 | 0 | 0 | | | | |\n| | | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | | +NodeByLabelScan | 7 | b:Person | 1000 | 0 | 0 | 256 | 0/0 | 0.000 | Fused in Pipeline 2 |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +Filter | 8 | rand() < \$autodouble_4 AND cache[a.id] = i | 15 | 0 | 2027 | | | | |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | +NodeByLabelScan | 9 | a:Person | 1000 | 20000 | 30000 | 8488 | 10002/0 | 6.158 | Fused in Pipeline 1 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Unwind | 10 | range(\$autoint_2, \$autoint_3) AS j | 100 | 10000 | 0 | | | | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| +Unwind | 11 | range(\$autoint_0, \$autoint_1) AS i | 10 | 100 | 0 | | 0/0 | 0.000 | Fused in Pipeline 0 |\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n\nTotal database accesses: 32027, total allocated memory: 10624\n" - , - "PIPELINED", - 0, - 1, - 1, - "PIPELINED", - 5, - 1, - 128, - '1', - 5.26, - '1', - 5.26, - 1, - 2.25, - 1, - 1 + dbHits: 0, + records: 0, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "ProduceResults@neo4j", + arguments: new ProfiledQueryPlanArguments( + globalMemory: 10624, + plannerImpl: "IDP", + memory: null, + stringRepresentation: "Cypher 5\n\nPlanner COST\n\nRuntime PIPELINED\n\nRuntime version 5.26\n\nBatch size 128\n\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| Operator | Id | Details | Estimated Rows | Rows | DB Hits | Memory (Bytes) | Page Cache Hits/Misses | Time (ms) | Pipeline |\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +ProduceResults | 0 | | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +EmptyResult | 1 | | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +Create | 2 | (a)-[anon_0:KNOWS]->(b), (b)-[anon_1:KNOWS]->(a) | 2 | 0 | 0 | | 0/0 | 0.000 | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+ |\n| +Filter | 3 | cache[a.id] < cache[b.id] | 2 | 0 | 0 | | 0/0 | 0.000 | In Pipeline 3 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Apply | 4 | | 8 | 0 | 0 | | 0/0 | | |\n| |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +CartesianProduct | 5 | | 8 | 0 | 0 | 1392 | | | In Pipeline 3 |\n| | |\\ +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | | +Filter | 6 | cache[b.id] = j | 50 | 0 | 0 | | | | |\n| | | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | | +NodeByLabelScan | 7 | b:Person | 1000 | 0 | 0 | 256 | 0/0 | 0.000 | Fused in Pipeline 2 |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| | +Filter | 8 | rand() < \$autodouble_4 AND cache[a.id] = i | 15 | 0 | 2027 | | | | |\n| | | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| | +NodeByLabelScan | 9 | a:Person | 1000 | 20000 | 30000 | 8488 | 10002/0 | 6.158 | Fused in Pipeline 1 |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n| +Unwind | 10 | range(\$autoint_2, \$autoint_3) AS j | 100 | 10000 | 0 | | | | |\n| | +----+--------------------------------------------------+----------------+-------+---------+----------------+ | | |\n| +Unwind | 11 | range(\$autoint_0, \$autoint_1) AS i | 10 | 100 | 0 | | 0/0 | 0.000 | Fused in Pipeline 0 |\n+----------------------+----+--------------------------------------------------+----------------+-------+---------+----------------+------------------------+-----------+---------------------+\n\nTotal database accesses: 32027, total allocated memory: 10624\n", + runtime: "PIPELINED", + time: 0, + pageCacheMisses: 0, + pageCacheHits: 0, + runtimeImpl: "PIPELINED", + version: 5, + dbHits: 0, + batchSize: 128, + details: "", + plannerVersion: 5.26, + pipelineInfo: "In Pipeline 3", + runtimeVersion: 5.26, + id: 0, + estimatedRows: 2.25, + planner: 'COST', + rows: 0, ), - [ + children: [ + // CHILD #1: EmptyResult@neo4j new ProfiledQueryPlan( - 0, - 0, - false, - 0, - 0, - 0.0, - 0, - "EmptyResult@neo4j", - new ProfiledQueryPlanArguments( - null, - null, - null, - null, - null, - 0, - 1, - 1, - null, - null, - 1, - null, - '', - null, - "1", - null, - 1, - 2.25, - '1', - 1 - + dbHits: 0, + records: 0, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "EmptyResult@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: null, + stringRepresentation: null, + runtime: null, + time: 0, + pageCacheMisses: 0, + pageCacheHits: 0, + runtimeImpl: null, + version: null, + dbHits: 0, + batchSize: null, + details: null, + // Using empty strings or nulls for fields not strictly needed + plannerVersion: null, + pipelineInfo: 'In Pipeline 3', + runtimeVersion: null, + id: 1, + estimatedRows: 2.25, + rows: 0 ), - - + children: [ + // CHILD #1.1: Create@neo4j + new ProfiledQueryPlan( + dbHits: 0, + records: 0, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "Create@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: null, + stringRepresentation: null, + runtime: null, + time: 0, + pageCacheMisses: null, + pageCacheHits: 0, + runtimeImpl: null, + version: null, + dbHits: 0, + batchSize: 0, + details: "(a)-[anon_0:KNOWS]->(b), (b)-[anon_1:KNOWS]->(a)", + plannerVersion: "", + pipelineInfo: "In Pipeline 3", + runtimeVersion: null, + id: 2, + estimatedRows: 2.25, + rows: 0 + ), + children: [ + // CHILD #1.1.1: Filter@neo4j (id=3) + new ProfiledQueryPlan( + dbHits: 0, + records: 0, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "Filter@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: null, + stringRepresentation: null, + runtime: null, + time: 0, + pageCacheMisses: null, + pageCacheHits: 0, + runtimeImpl: null, + version: null, + dbHits: 0, + batchSize: 0, + details: "cache[a.id] < cache[b.id]", + plannerVersion: "", + pipelineInfo: "In Pipeline 3", + runtimeVersion: null, + id: 3, + estimatedRows: 2.25, + rows: 0 + ), + children: [ + // CHILD #1.1.1.1: Apply@neo4j (id=4) + new ProfiledQueryPlan( + dbHits: 0, + records: 0, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "Apply@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: null, + stringRepresentation: null, + runtime: null, + time: null, + pageCacheMisses: null, + pageCacheHits: 0, + runtimeImpl: null, + version: null, + dbHits: 0, + batchSize: 0, + details: "", + plannerVersion: "", + pipelineInfo: "", + runtimeVersion: null, + id: 4, + estimatedRows: 7.5, + rows: 0 + ), + children: [ + // CHILD #1.1.1.1.1: Unwind@neo4j (id=10) + new ProfiledQueryPlan( + dbHits: 0, + records: 10000, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "Unwind@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: null, + stringRepresentation: null, + runtime: null, + time: null, + pageCacheMisses: null, + pageCacheHits: 0, + runtimeImpl: null, + version: null, + dbHits: 0, + batchSize: 0, + details: "range(\$autoint_2, \$autoint_3) AS j", + plannerVersion: "", + pipelineInfo: "Fused in Pipeline 0", + runtimeVersion: null, + id: 10, + estimatedRows: 100.0, + rows: 10000 + ), + children: [ + // The second Unwind@neo4j (id=11) + new ProfiledQueryPlan( + dbHits: 0, + records: 100, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "Unwind@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: null, + stringRepresentation: null, + runtime: null, + time: 0, + pageCacheMisses: null, + pageCacheHits: 0, + runtimeImpl: null, + version: null, + dbHits: 0, + batchSize: 0, + details: "range(\$autoint_0, \$autoint_1) AS i", + plannerVersion: "", + pipelineInfo: "Fused in Pipeline 0", + runtimeVersion: null, + id: 11, + estimatedRows: 10.0, + rows: 100 + ) + ) + ] + ), + // CHILD #1.1.1.1.2: CartesianProduct@neo4j (id=5) + new ProfiledQueryPlan( + dbHits: 0, + records: 0, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "CartesianProduct@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: 1392, + stringRepresentation: null, + runtime: null, + time: null, + pageCacheMisses: null, + pageCacheHits: 0, + runtimeImpl: null, + version: null, + dbHits: 0, + batchSize: 0, + details: "", + plannerVersion: "", + pipelineInfo: "In Pipeline 3", + runtimeVersion: null, + id: 5, + estimatedRows: 7.5, + rows: 0 + ), + children: [ + // CHILD #1.1.1.1.2.1: Filter@neo4j (id=8) + new ProfiledQueryPlan( + dbHits: 2027, + records: 0, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "Filter@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: null, + stringRepresentation: null, + runtime: null, + time: null, + pageCacheMisses: null, + pageCacheHits: 0, + runtimeImpl: null, + version: null, + dbHits: 2027, + batchSize: 0, + details: "rand() < \$autodouble_4 AND cache[a.id] = i", + plannerVersion: "", + pipelineInfo: "Fused in Pipeline 1", + runtimeVersion: null, + id: 8, + estimatedRows: 15.0, + rows: 0 + ), + children: [ + // NodeByLabelScan@neo4j (id=9) + new ProfiledQueryPlan( + dbHits: 30000, + records: 20000, + hasPageCacheStats: true, + pageCacheHits: 10002, + pageCacheMisses: 0, + pageCacheHitRatio: 1.0, + time: 6157670, + operatorType: "NodeByLabelScan@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: 8488, + stringRepresentation: null, + runtime: null, + time: 6157670, + pageCacheMisses: 0, + pageCacheHits: 10002, + runtimeImpl: null, + version: null, + dbHits: 30000, + batchSize: 0, + details: "a:Person", + plannerVersion: "", + pipelineInfo: "Fused in Pipeline 1", + runtimeVersion: null, + id: 9, + estimatedRows: 1000.0, + rows: 20000, + ) + ) + ] + ), + // CHILD #1.1.1.1.2.2: Filter@neo4j (id=6) + new ProfiledQueryPlan( + dbHits: 0, + records: 0, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "Filter@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: null, + stringRepresentation: null, + runtime: null, + time: null, + pageCacheMisses: null, + pageCacheHits: 0, + runtimeImpl: null, + version: null, + dbHits: 0, + batchSize: 0, + details: "cache[b.id] = j", + plannerVersion: "", + pipelineInfo: "Fused in Pipeline 2", + runtimeVersion: null, + id: 6, + estimatedRows: 50.0, + rows: 0 + ), + children: [ + // NodeByLabelScan@neo4j (id=7) + new ProfiledQueryPlan( + dbHits: 0, + records: 0, + hasPageCacheStats: false, + pageCacheHits: 0, + pageCacheMisses: 0, + pageCacheHitRatio: 0.0, + time: 0, + operatorType: "NodeByLabelScan@neo4j", + arguments: new ProfiledQueryPlanArguments( + plannerImpl: null, + memory: 256, + stringRepresentation: null, + runtime: null, + time: 0, + pageCacheMisses: null, + pageCacheHits: 0, + runtimeImpl: null, + version: null, + dbHits: 0, + batchSize: 0, + details: "b:Person", + plannerVersion: "", + pipelineInfo: "Fused in Pipeline 2", + runtimeVersion: null, + id: 7, + estimatedRows: 1000.0, + rows: 0 + ) + ) + ] + ) + ] + ) + ] + ) + ] + ) + ] + ) + ] ) ] - ) - - -); \ No newline at end of file +); diff --git a/tests/resources/responses/complex-query-profile.json b/tests/resources/responses/complex-query-profile.json index 9f61e414..d4e02145 100644 --- a/tests/resources/responses/complex-query-profile.json +++ b/tests/resources/responses/complex-query-profile.json @@ -62,7 +62,8 @@ "PageCacheHits" : 0 }, "identifiers" : [ "j", "a", "i", "b", "anon_0", "anon_1" ], - "children" : [ { + "children" : [ + { "dbHits" : 0, "records" : 0, "hasPageCacheStats" : false, From 5bf14cbc99a84d39e1295c18550322db80aa3b9c Mon Sep 17 00:00:00 2001 From: Pratiksha Date: Mon, 20 Jan 2025 11:20:56 +0530 Subject: [PATCH 7/9] Applied CS-fixer --- .php-cs-fixer.cache | 2 +- src/Neo4jQueryAPI.php | 3 +- src/Objects/ProfiledQueryPlan.php | 2 +- src/Objects/ProfiledQueryPlanArguments.php | 74 +++++++++++----------- src/Results/ResultSet.php | 5 +- 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache index c2d9225a..a37fa84c 100644 --- a/.php-cs-fixer.cache +++ b/.php-cs-fixer.cache @@ -1 +1 @@ -{"php":"8.3.6","version":"3.68.0:v3.68.0#73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true},"hashes":{"src\/OGM.php":"93aae9c7afc8dbfd5aa00bc1d264ad19","src\/Neo4jQueryAPI.php":"30e5405ec8eb4b5dd202b9fb29f89d32","src\/Results\/ResultRow.php":"a355cae3f815c5b12e3eaf09200e9378","src\/Results\/ResultSet.php":"5f7748a356bf0fb30403e3c5a411bd24","src\/Exception\/Neo4jException.php":"891a142e4cb2932f8d3e6bcf9dffe630","src\/Profile.php":"4ee46fef850bdebf767af5cacaa97d32","src\/Objects\/Path.php":"278df6c382797caaac604186216180dd","src\/Objects\/Node.php":"565fcc90fdf0035b9d019541eea500cf","src\/Objects\/ProfiledQueryPlanArguments.php":"e1f4ba1e4701d9c3383eaee1a40c30cf","src\/Objects\/Person.php":"59814ca77fc40d172b232e7c8a638c39","src\/Objects\/Point.php":"085b951053c0edece358b89b5afeac7d","src\/Objects\/ProfiledQueryPlan.php":"4709c2a11e73003fc1c027a6a8a62971","src\/Objects\/Bookmarks.php":"e9a1155f1d871e20880b5d92f92a60cd","src\/Objects\/ResultCounters.php":"548cf41b8590b5e366002a5f80d15ed1","src\/Objects\/Relationship.php":"7bff01461f7156c81c0ab94ca8a6bf53","src\/Transaction.php":"cba4e1ad958b2d15952b74148fd96c21"}} \ No newline at end of file +{"php":"8.3.6","version":"3.68.0:v3.68.0#73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"strict_param":true},"hashes":{"tests\/resources\/expected\/complex-query-profile.php":"003fa2fdf787e68d6fb3e72d698df763","tests\/Unit\/Neo4jExceptionUnitTest.php":"0d7842780eeb9729d501831ee55df0d8","tests\/Unit\/ResultRowTest.php":"f5ee9f21d2439793a290e8ab946a7f32","tests\/Unit\/Neo4jQueryAPIUnitTest.php":"54be7f7b0f9dcf13d62c4912127583b9","tests\/Integration\/Neo4jQueryAPIIntegrationTest.php":"44977ffd6c09c505b00c8ef4857b8bfd","tests\/Integration\/Neo4jOGMTest.php":"73136b2d28fbb4fa298467d1ab3e18c8","src\/OGM.php":"93aae9c7afc8dbfd5aa00bc1d264ad19","src\/Neo4jQueryAPI.php":"9f2e978ed0191040e303f84846a7f556","src\/Results\/ResultRow.php":"ad55ec1bd999a8f6ad6b18874c4017b5","src\/Results\/ResultSet.php":"5f7748a356bf0fb30403e3c5a411bd24","src\/Exception\/Neo4jException.php":"dfb0f6933b9d3913c5495ba6d801d5f1","src\/Objects\/Path.php":"88c95962a6316ba7aa2fa3f0f6e31627","src\/Objects\/Node.php":"4a8ab7b8bd1981ee4d35d8c52b81c7c3","src\/Objects\/ProfiledQueryPlanArguments.php":"1be7b230a034a72c13349a5670a34a2f","src\/Objects\/Person.php":"f2f469937660f5454761e4f31154e081","src\/Objects\/Point.php":"169715b2157e08482e420374e6ca4cc3","src\/Objects\/ProfiledQueryPlan.php":"4709c2a11e73003fc1c027a6a8a62971","src\/Objects\/Bookmarks.php":"50f89ca88b2df817433ce8237ccc0f18","src\/Objects\/ResultCounters.php":"a9372c98fe7bede10cb004af30ea502f","src\/Objects\/Relationship.php":"f6347c0260780d4f5d2dc407dc97e25e","src\/Transaction.php":"e456922858b31d87b17ca47d25d58474"}} \ No newline at end of file diff --git a/src/Neo4jQueryAPI.php b/src/Neo4jQueryAPI.php index 6aa2f18b..4b214f30 100644 --- a/src/Neo4jQueryAPI.php +++ b/src/Neo4jQueryAPI.php @@ -17,7 +17,6 @@ class Neo4jQueryAPI { - private Client $client; public function __construct(Client $client) @@ -62,7 +61,7 @@ public function run(string $cypher, array $parameters = [], string $database = ' ]); $contents = $response->getBody()->getContents(); - $data = json_decode($contents, true, flags: JSON_THROW_ON_ERROR); + $data = json_decode($contents, true, flags: JSON_THROW_ON_ERROR); $ogm = new OGM(); $keys = $data['data']['fields'] ?? []; diff --git a/src/Objects/ProfiledQueryPlan.php b/src/Objects/ProfiledQueryPlan.php index 14251129..f6ab9c91 100644 --- a/src/Objects/ProfiledQueryPlan.php +++ b/src/Objects/ProfiledQueryPlan.php @@ -28,7 +28,7 @@ public function __construct( ?float $pageCacheHitRatio = 0.0, ?int $time = 0, ?string $operatorType = '', - ProfiledQueryPlanArguments $arguments , + ProfiledQueryPlanArguments $arguments, array $children = [] // Accept an array of children, default to empty array ) { $this->dbHits = $dbHits ?? 0; diff --git a/src/Objects/ProfiledQueryPlanArguments.php b/src/Objects/ProfiledQueryPlanArguments.php index 3329ba85..6943116c 100644 --- a/src/Objects/ProfiledQueryPlanArguments.php +++ b/src/Objects/ProfiledQueryPlanArguments.php @@ -5,123 +5,125 @@ class ProfiledQueryPlanArguments { public function __construct( - private readonly ?int $globalMemory = null, + private readonly ?int $globalMemory = null, private readonly ?string $plannerImpl = null, - private readonly ?int $memory = null, + private readonly ?int $memory = null, private readonly ?string $stringRepresentation = null, private readonly ?string $runtime = null, - private readonly ?int $time = null, - private readonly ?int $pageCacheMisses = null, - private readonly ?int $pageCacheHits = null, + private readonly ?int $time = null, + private readonly ?int $pageCacheMisses = null, + private readonly ?int $pageCacheHits = null, private readonly ?string $runtimeImpl = null, - private readonly ?int $version = null, - private readonly ?int $dbHits = null, - private readonly ?int $batchSize = null, + private readonly ?int $version = null, + private readonly ?int $dbHits = null, + private readonly ?int $batchSize = null, private readonly ?string $details = null, private readonly ?string $plannerVersion = null, private readonly ?string $pipelineInfo = null, private readonly ?string $runtimeVersion = null, - private readonly ?int $id = null, - private readonly ?float $estimatedRows = null, + private readonly ?int $id = null, + private readonly ?float $estimatedRows = null, private readonly ?string $planner = null, - private readonly ?int $rows = null - ) - { + private readonly ?int $rows = null + ) { } - public function getGlobalMemory(): int + public function getGlobalMemory(): ?int { return $this->globalMemory; } - public function getPlannerImpl(): string + public function getPlannerImpl(): ?string { return $this->plannerImpl; } - public function getMemory(): int + public function getMemory(): ?int { return $this->memory; } - public function getStringRepresentation(): string + public function getStringRepresentation(): ?string { return $this->stringRepresentation; } - public function getRuntime(): string + public function getRuntime(): ?string { return $this->runtime; } - public function getTime(): int + public function getTime(): ?int { return $this->time; } - public function getPageCacheMisses(): int + + public function getPageCacheMisses(): ?int { return $this->pageCacheMisses; } - private function getPageCacheHits():int - { - return $this->pageCacheHits; - } - public function getRuntimeImpl(): string + private function getPageCacheHits(): ?int + { + return $this->pageCacheHits; + } + + public function getRuntimeImpl(): ?string { return $this->runtimeImpl; } - public function getVersion(): string + + public function getVersion(): ?int { return $this->version; } - public function getDbHits(): int + public function getDbHits(): ?int { return $this->dbHits; } - public function getBatchSize(): int + public function getBatchSize(): ?int { return $this->batchSize; } - public function getDetails(): string + public function getDetails(): ?string { return $this->details; } - public function getPlannerVersion(): string + public function getPlannerVersion(): ?string { return $this->plannerVersion; } - public function getPipelineInfo(): string + public function getPipelineInfo(): ?string { return $this->pipelineInfo; } - public function getRuntimeVersion(): string + public function getRuntimeVersion(): ?string { return $this->runtimeVersion; } - public function getId(): int + public function getId(): ?int { return $this->id; } - public function getEstimatedRows(): float + public function getEstimatedRows(): ?float { return $this->estimatedRows; } - public function getPlanner(): string + public function getPlanner(): ?string { return $this->planner; } - public function getRows(): int + public function getRows(): ?int { return $this->rows; } diff --git a/src/Results/ResultSet.php b/src/Results/ResultSet.php index 418cc5cf..b822615f 100644 --- a/src/Results/ResultSet.php +++ b/src/Results/ResultSet.php @@ -23,8 +23,7 @@ public function __construct( private Bookmarks $bookmarks, private ?ProfiledQueryPlan $profiledQueryPlan = null, private ?ProfiledQueryPlanArguments $profiledQueryPlanArguments = null - ) - { + ) { } public function getIterator(): Traversable @@ -43,7 +42,7 @@ public function getProfiledQueryPlan(): ?ProfiledQueryPlan public function getChildQueryPlan(): ?ChildQueryPlan { - return $this->childQueryPlan; + return $this->childQueryPlan; } public function count(): int From 9195c5af94be1f3bffdda4c85e0c55211039fdc4 Mon Sep 17 00:00:00 2001 From: Pratiksha Date: Mon, 20 Jan 2025 13:30:46 +0530 Subject: [PATCH 8/9] updated the test with identifiers parameter --- src/Neo4jQueryAPI.php | 8 +-- src/Objects/ProfiledQueryPlan.php | 50 +++++++++++++++---- .../expected/complex-query-profile.php | 30 ++++++----- 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/src/Neo4jQueryAPI.php b/src/Neo4jQueryAPI.php index 4b214f30..38874c9b 100644 --- a/src/Neo4jQueryAPI.php +++ b/src/Neo4jQueryAPI.php @@ -164,7 +164,7 @@ private function createProfileData(array $data): ProfiledQueryPlan rows: $mappedArguments['Rows' ?? null] ); - + $identifiers = $data['identifiers'] ?? []; $profiledQueryPlan = new ProfiledQueryPlan( $data['dbHits'], $data['records'], @@ -174,9 +174,11 @@ private function createProfileData(array $data): ProfiledQueryPlan $data['pageCacheHitRatio'], $data['time'], $data['operatorType'], - $queryArguments - ); + $queryArguments, + children: [], + identifiers: $identifiers + ); // Process children recursively foreach ($data['children'] as $child) { $childQueryPlan = $this->createProfileData($child); diff --git a/src/Objects/ProfiledQueryPlan.php b/src/Objects/ProfiledQueryPlan.php index f6ab9c91..f35ea637 100644 --- a/src/Objects/ProfiledQueryPlan.php +++ b/src/Objects/ProfiledQueryPlan.php @@ -2,7 +2,7 @@ namespace Neo4j\QueryAPI\Objects; -class ProfiledQueryPlan extends \Neo4j\QueryAPI\Objects\Bookmarks +class ProfiledQueryPlan { private int $dbHits; private int $records; @@ -19,17 +19,23 @@ class ProfiledQueryPlan extends \Neo4j\QueryAPI\Objects\Bookmarks */ private array $children; + /** + * @var string[] + */ + private array $identifiers; + public function __construct( - ?int $dbHits = 0, // Default to 0 if null - ?int $records = 0, - ?bool $hasPageCacheStats = false, - ?int $pageCacheHits = 0, - ?int $pageCacheMisses = 0, - ?float $pageCacheHitRatio = 0.0, - ?int $time = 0, - ?string $operatorType = '', - ProfiledQueryPlanArguments $arguments, - array $children = [] // Accept an array of children, default to empty array + ?int $dbHits , + ?int $records , + ?bool $hasPageCacheStats , + ?int $pageCacheHits , + ?int $pageCacheMisses , + ?float $pageCacheHitRatio , + ?int $time , + ?string $operatorType, + ProfiledQueryPlanArguments $arguments , + ?array $children=[], + array $identifiers=[] // Default to an empty array ) { $this->dbHits = $dbHits ?? 0; $this->records = $records ?? 0; @@ -41,6 +47,7 @@ public function __construct( $this->operatorType = $operatorType ?? ''; $this->arguments = $arguments; $this->children = $children ?? []; + $this->identifiers = $identifiers; } public function getDbHits(): int @@ -100,4 +107,25 @@ public function addChild(ProfiledQueryPlan|ProfiledQueryPlanArguments $child): v { $this->children[] = $child; } + + /** + * @return string[] + */ + public function getIdentifiers(): array + { + return $this->identifiers; + } + + /** + * @param string[] $identifiers + */ + public function setIdentifiers(array $identifiers): void + { + $this->identifiers = $identifiers; + } + + public function addIdentifier(string $identifier): void + { + $this->identifiers[] = $identifier; + } } diff --git a/tests/resources/expected/complex-query-profile.php b/tests/resources/expected/complex-query-profile.php index 4ab3e442..12635dff 100644 --- a/tests/resources/expected/complex-query-profile.php +++ b/tests/resources/expected/complex-query-profile.php @@ -242,9 +242,10 @@ id: 11, estimatedRows: 10.0, rows: 100 - ) + ),identifiers: ["i"] ) - ] + ],identifiers: ["i","j"] + ), // CHILD #1.1.1.1.2: CartesianProduct@neo4j (id=5) new ProfiledQueryPlan( @@ -337,9 +338,12 @@ id: 9, estimatedRows: 1000.0, rows: 20000, - ) + ),identifiers: ["i","j","a"] + + ) - ] + ],identifiers: ["i","j","a"] + ), // CHILD #1.1.1.1.2.2: Filter@neo4j (id=6) new ProfiledQueryPlan( @@ -401,20 +405,22 @@ id: 7, estimatedRows: 1000.0, rows: 0 - ) + ),identifiers: ["i","j","b"] ) - ] + ],identifiers: ["i","j","b"] ) - ] + ],identifiers: ["i","j","a","b"] ) - ] + ],identifiers: ["i","j","a","b"] ) - ] + ], + + identifiers: ["i","j","a","b"] ) - ] + ],identifiers: ["j","a","i","b","anon_0","anon_1"] ) - ] + ],identifiers: ["j","a","i","b","anon_0","anon_1"] ) - ] + ],identifiers: ["j","a","i","b","anon_0","anon_1"] ) ); From b6158990a88e52e5e42e0a3aad2da29c8ee4ef7b Mon Sep 17 00:00:00 2001 From: Pratiksha Date: Mon, 20 Jan 2025 14:15:24 +0530 Subject: [PATCH 9/9] updated test with identifiers --- .php-cs-fixer.cache | 2 +- src/Neo4jQueryAPI.php | 1 - src/Objects/ProfiledQueryPlan.php | 20 +++++----- .../expected/complex-query-profile.php | 38 +++++++++++-------- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache index a37fa84c..378cd40f 100644 --- a/.php-cs-fixer.cache +++ b/.php-cs-fixer.cache @@ -1 +1 @@ -{"php":"8.3.6","version":"3.68.0:v3.68.0#73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"strict_param":true},"hashes":{"tests\/resources\/expected\/complex-query-profile.php":"003fa2fdf787e68d6fb3e72d698df763","tests\/Unit\/Neo4jExceptionUnitTest.php":"0d7842780eeb9729d501831ee55df0d8","tests\/Unit\/ResultRowTest.php":"f5ee9f21d2439793a290e8ab946a7f32","tests\/Unit\/Neo4jQueryAPIUnitTest.php":"54be7f7b0f9dcf13d62c4912127583b9","tests\/Integration\/Neo4jQueryAPIIntegrationTest.php":"44977ffd6c09c505b00c8ef4857b8bfd","tests\/Integration\/Neo4jOGMTest.php":"73136b2d28fbb4fa298467d1ab3e18c8","src\/OGM.php":"93aae9c7afc8dbfd5aa00bc1d264ad19","src\/Neo4jQueryAPI.php":"9f2e978ed0191040e303f84846a7f556","src\/Results\/ResultRow.php":"ad55ec1bd999a8f6ad6b18874c4017b5","src\/Results\/ResultSet.php":"5f7748a356bf0fb30403e3c5a411bd24","src\/Exception\/Neo4jException.php":"dfb0f6933b9d3913c5495ba6d801d5f1","src\/Objects\/Path.php":"88c95962a6316ba7aa2fa3f0f6e31627","src\/Objects\/Node.php":"4a8ab7b8bd1981ee4d35d8c52b81c7c3","src\/Objects\/ProfiledQueryPlanArguments.php":"1be7b230a034a72c13349a5670a34a2f","src\/Objects\/Person.php":"f2f469937660f5454761e4f31154e081","src\/Objects\/Point.php":"169715b2157e08482e420374e6ca4cc3","src\/Objects\/ProfiledQueryPlan.php":"4709c2a11e73003fc1c027a6a8a62971","src\/Objects\/Bookmarks.php":"50f89ca88b2df817433ce8237ccc0f18","src\/Objects\/ResultCounters.php":"a9372c98fe7bede10cb004af30ea502f","src\/Objects\/Relationship.php":"f6347c0260780d4f5d2dc407dc97e25e","src\/Transaction.php":"e456922858b31d87b17ca47d25d58474"}} \ No newline at end of file +{"php":"8.3.6","version":"3.68.0:v3.68.0#73f78d8b2b34a0dd65fedb434a602ee4c2c8ad4c","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":{"tokens":["use"]},"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"strict_param":true},"hashes":{"tests\/Unit\/Neo4jExceptionUnitTest.php":"0d7842780eeb9729d501831ee55df0d8","tests\/Unit\/ResultRowTest.php":"f5ee9f21d2439793a290e8ab946a7f32","tests\/Unit\/Neo4jQueryAPIUnitTest.php":"54be7f7b0f9dcf13d62c4912127583b9","tests\/Integration\/Neo4jQueryAPIIntegrationTest.php":"44977ffd6c09c505b00c8ef4857b8bfd","tests\/Integration\/Neo4jOGMTest.php":"73136b2d28fbb4fa298467d1ab3e18c8","src\/OGM.php":"93aae9c7afc8dbfd5aa00bc1d264ad19","src\/Results\/ResultRow.php":"ad55ec1bd999a8f6ad6b18874c4017b5","src\/Results\/ResultSet.php":"5f7748a356bf0fb30403e3c5a411bd24","src\/Exception\/Neo4jException.php":"dfb0f6933b9d3913c5495ba6d801d5f1","src\/Objects\/Path.php":"88c95962a6316ba7aa2fa3f0f6e31627","src\/Objects\/Node.php":"4a8ab7b8bd1981ee4d35d8c52b81c7c3","src\/Objects\/ProfiledQueryPlanArguments.php":"1be7b230a034a72c13349a5670a34a2f","src\/Objects\/Person.php":"f2f469937660f5454761e4f31154e081","src\/Objects\/Point.php":"169715b2157e08482e420374e6ca4cc3","src\/Objects\/Bookmarks.php":"50f89ca88b2df817433ce8237ccc0f18","src\/Objects\/ResultCounters.php":"a9372c98fe7bede10cb004af30ea502f","src\/Objects\/Relationship.php":"f6347c0260780d4f5d2dc407dc97e25e","src\/Transaction.php":"e456922858b31d87b17ca47d25d58474","tests\/resources\/expected\/complex-query-profile.php":"cc2b1e7e731c30a8855d9fa368cd55f3","src\/Neo4jQueryAPI.php":"8bffb787a834b58523e89fc9e5c19fe3","src\/Objects\/ProfiledQueryPlan.php":"d9ba608f3177426ea34d73276d75f20b"}} \ No newline at end of file diff --git a/src/Neo4jQueryAPI.php b/src/Neo4jQueryAPI.php index 38874c9b..cc315979 100644 --- a/src/Neo4jQueryAPI.php +++ b/src/Neo4jQueryAPI.php @@ -177,7 +177,6 @@ private function createProfileData(array $data): ProfiledQueryPlan $queryArguments, children: [], identifiers: $identifiers - ); // Process children recursively foreach ($data['children'] as $child) { diff --git a/src/Objects/ProfiledQueryPlan.php b/src/Objects/ProfiledQueryPlan.php index f35ea637..a32d314f 100644 --- a/src/Objects/ProfiledQueryPlan.php +++ b/src/Objects/ProfiledQueryPlan.php @@ -25,17 +25,17 @@ class ProfiledQueryPlan private array $identifiers; public function __construct( - ?int $dbHits , - ?int $records , - ?bool $hasPageCacheStats , - ?int $pageCacheHits , - ?int $pageCacheMisses , - ?float $pageCacheHitRatio , - ?int $time , + ?int $dbHits, + ?int $records, + ?bool $hasPageCacheStats, + ?int $pageCacheHits, + ?int $pageCacheMisses, + ?float $pageCacheHitRatio, + ?int $time, ?string $operatorType, - ProfiledQueryPlanArguments $arguments , - ?array $children=[], - array $identifiers=[] // Default to an empty array + ProfiledQueryPlanArguments $arguments, + ?array $children = [], + array $identifiers = [] // Default to an empty array ) { $this->dbHits = $dbHits ?? 0; $this->records = $records ?? 0; diff --git a/tests/resources/expected/complex-query-profile.php b/tests/resources/expected/complex-query-profile.php index 12635dff..858b88cb 100644 --- a/tests/resources/expected/complex-query-profile.php +++ b/tests/resources/expected/complex-query-profile.php @@ -242,10 +242,11 @@ id: 11, estimatedRows: 10.0, rows: 100 - ),identifiers: ["i"] + ), + identifiers: ["i"] ) - ],identifiers: ["i","j"] - + ], + identifiers: ["i","j"] ), // CHILD #1.1.1.1.2: CartesianProduct@neo4j (id=5) new ProfiledQueryPlan( @@ -338,12 +339,11 @@ id: 9, estimatedRows: 1000.0, rows: 20000, - ),identifiers: ["i","j","a"] - - + ), + identifiers: ["i","j","a"] ) - ],identifiers: ["i","j","a"] - + ], + identifiers: ["i","j","a"] ), // CHILD #1.1.1.1.2.2: Filter@neo4j (id=6) new ProfiledQueryPlan( @@ -405,22 +405,28 @@ id: 7, estimatedRows: 1000.0, rows: 0 - ),identifiers: ["i","j","b"] + ), + identifiers: ["i","j","b"] ) - ],identifiers: ["i","j","b"] + ], + identifiers: ["i","j","b"] ) - ],identifiers: ["i","j","a","b"] + ], + identifiers: ["i","j","a","b"] ) - ],identifiers: ["i","j","a","b"] + ], + identifiers: ["i","j","a","b"] ) ], - identifiers: ["i","j","a","b"] ) - ],identifiers: ["j","a","i","b","anon_0","anon_1"] + ], + identifiers: ["j","a","i","b","anon_0","anon_1"] ) - ],identifiers: ["j","a","i","b","anon_0","anon_1"] + ], + identifiers: ["j","a","i","b","anon_0","anon_1"] ) - ],identifiers: ["j","a","i","b","anon_0","anon_1"] + ], + identifiers: ["j","a","i","b","anon_0","anon_1"] ) );