From 767d99944b20ee162885294db5795edd7ea1c304 Mon Sep 17 00:00:00 2001 From: Simon Mundy Date: Thu, 29 May 2025 09:47:26 +1000 Subject: [PATCH 1/9] Initial commit --- .gitignore | 7 + bin/install-deps.sh | 7 + compose.yml | 31 + composer.json | 79 + composer.lock | 5579 +++++++++++++++++ coveralls.yml | 2 + docker/databases/pgsql/Dockerfile | 3 + docker/php/Dockerfile | 26 + docker/php/conf.d/error_reporting.ini | 1 + docker/php/conf.d/xdebug.ini | 6 + phpunit.xml.dist | 37 + psalm-baseline.xml | 1063 ++++ psalm.xml.dist | 71 + psr-container.php.stub | 23 + renovate.json | 6 + src/Adapter.php | 17 + src/AdapterServiceFactory.php | 37 + src/ConfigProvider.php | 32 + src/Driver/DatabasePlatformNameTrait.php | 23 + src/Driver/Pdo/Connection.php | 333 + src/Driver/Pdo/DriverFactory.php | 17 + src/Driver/Pdo/Pdo.php | 85 + src/Driver/Pdo/Result.php | 9 + src/Driver/Pdo/Statement.php | 9 + src/Driver/Pgsql/Connection.php | 286 + src/Driver/Pgsql/Pgsql.php | 223 + src/Driver/Pgsql/PgsqlConfig.php | 56 + src/Driver/Pgsql/Result.php | 193 + src/Driver/Pgsql/Statement.php | 231 + src/Module.php | 15 + src/Platform/Postgresql.php | 142 + src/test.php | 20 + .../Driver/Pdo/Postgresql/AdapterTest.php | 14 + .../Driver/Pdo/Postgresql/AdapterTrait.php | 33 + .../Pdo/Postgresql/TableGatewayTest.php | 31 + .../Adapter/Platform/PostgresqlTest.php | 88 + .../Platform/PgsqlFixtureLoader.php | 104 + test/integration/TestFixtures/pgsql.sql | 29 + .../Adapter/AdapterServiceFactoryTest.php | 115 + test/unit/Adapter/AdapterTest.php | 261 + test/unit/Adapter/ConfigProviderTest.php | 50 + test/unit/Adapter/ModuleTest.php | 42 + 42 files changed, 9436 insertions(+) create mode 100644 .gitignore create mode 100755 bin/install-deps.sh create mode 100644 compose.yml create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 coveralls.yml create mode 100644 docker/databases/pgsql/Dockerfile create mode 100644 docker/php/Dockerfile create mode 100644 docker/php/conf.d/error_reporting.ini create mode 100644 docker/php/conf.d/xdebug.ini create mode 100644 phpunit.xml.dist create mode 100644 psalm-baseline.xml create mode 100644 psalm.xml.dist create mode 100644 psr-container.php.stub create mode 100644 renovate.json create mode 100644 src/Adapter.php create mode 100644 src/AdapterServiceFactory.php create mode 100644 src/ConfigProvider.php create mode 100644 src/Driver/DatabasePlatformNameTrait.php create mode 100644 src/Driver/Pdo/Connection.php create mode 100644 src/Driver/Pdo/DriverFactory.php create mode 100644 src/Driver/Pdo/Pdo.php create mode 100644 src/Driver/Pdo/Result.php create mode 100644 src/Driver/Pdo/Statement.php create mode 100644 src/Driver/Pgsql/Connection.php create mode 100644 src/Driver/Pgsql/Pgsql.php create mode 100644 src/Driver/Pgsql/PgsqlConfig.php create mode 100644 src/Driver/Pgsql/Result.php create mode 100644 src/Driver/Pgsql/Statement.php create mode 100644 src/Module.php create mode 100644 src/Platform/Postgresql.php create mode 100644 src/test.php create mode 100644 test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTest.php create mode 100644 test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTrait.php create mode 100644 test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php create mode 100644 test/integration/Adapter/Platform/PostgresqlTest.php create mode 100644 test/integration/Platform/PgsqlFixtureLoader.php create mode 100644 test/integration/TestFixtures/pgsql.sql create mode 100644 test/unit/Adapter/AdapterServiceFactoryTest.php create mode 100644 test/unit/Adapter/AdapterTest.php create mode 100644 test/unit/Adapter/ConfigProviderTest.php create mode 100644 test/unit/Adapter/ModuleTest.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3df39e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/.phpcs-cache +/.phpunit.cache +/.phpunit.result.cache +/phpunit.xml +/vendor/ +/xdebug_filter.php +/clover.xml diff --git a/bin/install-deps.sh b/bin/install-deps.sh new file mode 100755 index 0000000..3101960 --- /dev/null +++ b/bin/install-deps.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +composer validate && \ +composer --ignore-platform-reqs install \ + --no-ansi --no-progress --no-scripts \ + --classmap-authoritative --no-interaction \ + --quiet \ No newline at end of file diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..0bb7326 --- /dev/null +++ b/compose.yml @@ -0,0 +1,31 @@ +services: + php: + build: + context: ./ + dockerfile: docker/php/Dockerfile + args: + - PHP_VERSION=${PHP_VERSION:-8.3.19} + volumes: + - ./:/var/www/html + depends_on: + - mysql + + mysql: + build: + context: ./ + dockerfile: docker/databases/mysql/Dockerfile + args: + - VERSION=${MYSQL_VERSION:-8.0.41} + ports: + - "3306:3306" + environment: + - MYSQL_DATABASE=${MYSQL_DATABASE:-laminasdb_test} + - MYSQL_USER=${MYSQL_USER:-user} + - MYSQL_PASSWORD=${MYSQL_PASSWORD:-password} + - MYSQL_RANDOM_ROOT_PASSWORD=${MYSQL_RANDOM_ROOT_PASSWORD:-yes} + volumes: + - ./test/integration/TestFixtures/mysql.sql:/docker-entrypoint-initdb.d/mysql.sql + healthcheck: + test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] + timeout: 20s + retries: 10 diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..54ed8c2 --- /dev/null +++ b/composer.json @@ -0,0 +1,79 @@ +{ + "name": "laminas/laminas-db-adapter-pgsql", + "description": "SQLite support for laminas-db", + "license": "BSD-3-Clause", + "keywords": [ + "laminas", + "pgsql", + "db" + ], + "homepage": "https://github.com/axleus/laminas-db-adapter-pgsql/discussions", + "support": { + "issues": "https://github.com/alxeus/laminas-db-adapter-pgsql/issues", + "source": "https://github.com/axleus/laminas-db-adapter-pgsql", + "forum": "https://github.com/axleus/laminas-db-adapter-pgsql/discussions" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "sort-packages": true, + "platform": { + "php": "8.2.99" + }, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, + "extra": { + "laminas": { + "component": "Laminas\\Db\\Pgsql", + "config-provider": "Laminas\\Db\\Pgsql\\ConfigProvider" + } + }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/axleus/laminas-db" + } + ], + "require": { + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "laminas/laminas-db": "dev-adapter-migration-mysql-refactor", + "ext-pdo": "*", + "ext-pdo_pgsql": "*" + }, + "require-dev": { + "laminas/laminas-coding-standard": "^3.0.1", + "phpunit/phpunit": "^11.5.15", + "psalm/plugin-phpunit": "^0.19.2", + "vimeo/psalm": "^6.8.8" + }, + "suggest": { + "ext-pgsql": "*", + "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" + }, + "autoload": { + "psr-4": { + "Laminas\\Db\\Pgsql\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "LaminasTest\\Db\\Pgsql\\": "test/unit/", + "LaminasIntegrationTest\\Db\\Pgsql\\": "test/integration/" + } + }, + "scripts": { + "check": [ + "@cs-check", + "@test" + ], + "cs-check": "phpcs", + "cs-fix": "phpcbf", + "test": "phpunit --colors=always --testsuite \"unit test\"", + "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", + "test-integration": "phpunit --colors=always --testsuite \"integration test\"", + "static-analysis": "psalm --shepherd --stats", + "upload-coverage": "coveralls -v" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..074c38c --- /dev/null +++ b/composer.lock @@ -0,0 +1,5579 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "ee3918e02f4a5515cf0c24f31cb8786b", + "packages": [ + { + "name": "brick/varexporter", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/brick/varexporter.git", + "reference": "84b2a7a91f69aa5d079aec5a0a7256ebf2dceb6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/varexporter/zipball/84b2a7a91f69aa5d079aec5a0a7256ebf2dceb6b", + "reference": "84b2a7a91f69aa5d079aec5a0a7256ebf2dceb6b", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.3", + "psalm/phar": "5.21.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\VarExporter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A powerful alternative to var_export(), which can export closures and objects without __set_state()", + "keywords": [ + "var_export" + ], + "support": { + "issues": "https://github.com/brick/varexporter/issues", + "source": "https://github.com/brick/varexporter/tree/0.5.0" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2024-05-10T17:15:19+00:00" + }, + { + "name": "laminas/laminas-db", + "version": "dev-adapter-migration-mysql-refactor", + "source": { + "type": "git", + "url": "https://github.com/axleus/laminas-db.git", + "reference": "a33223ab8deeaa6b17366f7a61fb8d2078a7efa3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/axleus/laminas-db/zipball/a33223ab8deeaa6b17366f7a61fb8d2078a7efa3", + "reference": "a33223ab8deeaa6b17366f7a61fb8d2078a7efa3", + "shasum": "" + }, + "require": { + "laminas/laminas-servicemanager": "^4.0.0", + "laminas/laminas-stdlib": "^3.20.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "conflict": { + "zendframework/zend-db": "*" + }, + "require-dev": { + "laminas/laminas-coding-standard": "^3.0.1", + "laminas/laminas-eventmanager": "^3.14.0", + "laminas/laminas-servicemanager": "^4.0.0", + "phpunit/phpunit": "^11.5.12", + "psalm/plugin-phpunit": "^0.19.2", + "rector/rector": "^2.0", + "vimeo/psalm": "^6.8.8" + }, + "suggest": { + "laminas/laminas-eventmanager": "Laminas\\EventManager component", + "laminas/laminas-hydrator": "(^5.0.0) Laminas\\Hydrator component for using HydratingResultSets", + "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" + }, + "type": "library", + "autoload": { + "psr-4": { + "Laminas\\Db\\": "src/", + "CustomRule\\PHPUnit\\": "rector/" + } + }, + "autoload-dev": { + "psr-4": { + "LaminasTest\\Db\\": "test/unit/", + "LaminasIntegrationTest\\Db\\": "test/integration/" + } + }, + "scripts": { + "check": [ + "@cs-check", + "@test" + ], + "cs-check": [ + "phpcs" + ], + "cs-fix": [ + "phpcbf" + ], + "test": [ + "phpunit --colors=always --testsuite \"unit test\"" + ], + "test-coverage": [ + "phpunit --colors=always --coverage-clover clover.xml" + ], + "test-integration": [ + "phpunit --colors=always --testsuite \"integration test\"" + ], + "static-analysis": [ + "psalm --shepherd --stats" + ], + "upload-coverage": [ + "coveralls -v" + ] + }, + "license": [ + "BSD-3-Clause" + ], + "description": "Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations", + "homepage": "https://laminas.dev", + "keywords": [ + "db", + "laminas" + ], + "support": { + "docs": "https://docs.laminas.dev/laminas-db/", + "issues": "https://github.com/laminas/laminas-db/issues", + "source": "https://github.com/laminas/laminas-db", + "rss": "https://github.com/laminas/laminas-db/releases.atom", + "chat": "https://laminas.dev/chat", + "forum": "https://discourse.laminas.dev" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/AXLEUS" + } + ], + "time": "2025-05-23T07:07:25+00:00" + }, + { + "name": "laminas/laminas-servicemanager", + "version": "4.4.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-servicemanager.git", + "reference": "74da44d07e493b834347123242d0047976fb9932" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/74da44d07e493b834347123242d0047976fb9932", + "reference": "74da44d07e493b834347123242d0047976fb9932", + "shasum": "" + }, + "require": { + "brick/varexporter": "^0.3.8 || ^0.4.0 || ^0.5.0", + "laminas/laminas-stdlib": "^3.19", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", + "psr/container": "^1.1 || ^2.0" + }, + "conflict": { + "laminas/laminas-code": "<4.10.0", + "zendframework/zend-code": "<3.3.1" + }, + "provide": { + "psr/container-implementation": "^1.0 || ^2.0" + }, + "require-dev": { + "composer/package-versions-deprecated": "^1.11.99.5", + "friendsofphp/proxy-manager-lts": "^1.0.18", + "laminas/laminas-cli": "^1.11", + "laminas/laminas-coding-standard": "~3.0.1", + "laminas/laminas-container-config-test": "^1.0", + "mikey179/vfsstream": "^1.6.12", + "phpbench/phpbench": "^1.4.0", + "phpunit/phpunit": "^10.5.44", + "psalm/plugin-phpunit": "^0.19.2", + "symfony/console": "^6.4.17 || ^7.0", + "vimeo/psalm": "^6.2.0" + }, + "suggest": { + "friendsofphp/proxy-manager-lts": "To handle lazy initialization of services", + "laminas/laminas-cli": "To consume CLI commands provided by this component" + }, + "type": "library", + "extra": { + "laminas": { + "module": "Laminas\\ServiceManager", + "config-provider": "Laminas\\ServiceManager\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Laminas\\ServiceManager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Factory-Driven Dependency Injection Container", + "homepage": "https://laminas.dev", + "keywords": [ + "PSR-11", + "dependency-injection", + "di", + "dic", + "laminas", + "service-manager", + "servicemanager" + ], + "support": { + "chat": "https://laminas.dev/chat", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-servicemanager/issues", + "source": "https://github.com/laminas/laminas-servicemanager/tree/4.4.0" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2025-02-04T06:13:50+00:00" + }, + { + "name": "laminas/laminas-stdlib", + "version": "3.20.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-stdlib.git", + "reference": "8974a1213be42c3e2f70b2c27b17f910291ab2f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/8974a1213be42c3e2f70b2c27b17f910291ab2f4", + "reference": "8974a1213be42c3e2f70b2c27b17f910291ab2f4", + "shasum": "" + }, + "require": { + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "conflict": { + "zendframework/zend-stdlib": "*" + }, + "require-dev": { + "laminas/laminas-coding-standard": "^3.0", + "phpbench/phpbench": "^1.3.1", + "phpunit/phpunit": "^10.5.38", + "psalm/plugin-phpunit": "^0.19.0", + "vimeo/psalm": "^5.26.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Laminas\\Stdlib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "SPL extensions, array utilities, error handlers, and more", + "homepage": "https://laminas.dev", + "keywords": [ + "laminas", + "stdlib" + ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-stdlib/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-stdlib/issues", + "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", + "source": "https://github.com/laminas/laminas-stdlib" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2024-10-29T13:46:07+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" + }, + "time": "2024-12-30T11:07:19+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + } + ], + "packages-dev": [ + { + "name": "amphp/amp", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/amp.git", + "reference": "7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/amp/zipball/7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9", + "reference": "7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "5.23.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php", + "src/Future/functions.php", + "src/Internal/functions.php" + ], + "psr-4": { + "Amp\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "https://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "support": { + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/v3.1.0" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-01-26T16:07:39+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/55a6bd071aec26fa2a3e002618c20c35e3df1b46", + "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/parser": "^1.1", + "amphp/pipeline": "^1", + "amphp/serialization": "^1", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2.3" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "5.22.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php", + "src/Internal/functions.php" + ], + "psr-4": { + "Amp\\ByteStream\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "https://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "support": { + "issues": "https://github.com/amphp/byte-stream/issues", + "source": "https://github.com/amphp/byte-stream/tree/v2.1.2" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-03-16T17:10:27+00:00" + }, + { + "name": "amphp/cache", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/cache.git", + "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/cache/zipball/46912e387e6aa94933b61ea1ead9cf7540b7797c", + "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/serialization": "^1", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Cache\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + } + ], + "description": "A fiber-aware cache API based on Amp and Revolt.", + "homepage": "https://amphp.org/cache", + "support": { + "issues": "https://github.com/amphp/cache/issues", + "source": "https://github.com/amphp/cache/tree/v2.0.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-19T03:38:06+00:00" + }, + { + "name": "amphp/dns", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/dns.git", + "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/dns/zipball/78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", + "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/cache": "^2", + "amphp/parser": "^1", + "amphp/process": "^2", + "daverandom/libdns": "^2.0.2", + "ext-filter": "*", + "ext-json": "*", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "5.20" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Dns\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Wright", + "email": "addr@daverandom.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "Async DNS resolution for Amp.", + "homepage": "https://github.com/amphp/dns", + "keywords": [ + "amp", + "amphp", + "async", + "client", + "dns", + "resolve" + ], + "support": { + "issues": "https://github.com/amphp/dns/issues", + "source": "https://github.com/amphp/dns/tree/v2.4.0" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-01-19T15:43:40+00:00" + }, + { + "name": "amphp/parallel", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/parallel.git", + "reference": "5113111de02796a782f5d90767455e7391cca190" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/parallel/zipball/5113111de02796a782f5d90767455e7391cca190", + "reference": "5113111de02796a782f5d90767455e7391cca190", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/cache": "^2", + "amphp/parser": "^1", + "amphp/pipeline": "^1", + "amphp/process": "^2", + "amphp/serialization": "^1", + "amphp/socket": "^2", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.18" + }, + "type": "library", + "autoload": { + "files": [ + "src/Context/functions.php", + "src/Context/Internal/functions.php", + "src/Ipc/functions.php", + "src/Worker/functions.php" + ], + "psr-4": { + "Amp\\Parallel\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" + } + ], + "description": "Parallel processing component for Amp.", + "homepage": "https://github.com/amphp/parallel", + "keywords": [ + "async", + "asynchronous", + "concurrent", + "multi-processing", + "multi-threading" + ], + "support": { + "issues": "https://github.com/amphp/parallel/issues", + "source": "https://github.com/amphp/parallel/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-12-21T01:56:09+00:00" + }, + { + "name": "amphp/parser", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/parser.git", + "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/parser/zipball/3cf1f8b32a0171d4b1bed93d25617637a77cded7", + "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Parser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A generator parser to make streaming parsers simple.", + "homepage": "https://github.com/amphp/parser", + "keywords": [ + "async", + "non-blocking", + "parser", + "stream" + ], + "support": { + "issues": "https://github.com/amphp/parser/issues", + "source": "https://github.com/amphp/parser/tree/v1.1.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-03-21T19:16:53+00:00" + }, + { + "name": "amphp/pipeline", + "version": "v1.2.3", + "source": { + "type": "git", + "url": "https://github.com/amphp/pipeline.git", + "reference": "7b52598c2e9105ebcddf247fc523161581930367" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/pipeline/zipball/7b52598c2e9105ebcddf247fc523161581930367", + "reference": "7b52598c2e9105ebcddf247fc523161581930367", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "php": ">=8.1", + "revolt/event-loop": "^1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.18" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Pipeline\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Asynchronous iterators and operators.", + "homepage": "https://amphp.org/pipeline", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "iterator", + "non-blocking" + ], + "support": { + "issues": "https://github.com/amphp/pipeline/issues", + "source": "https://github.com/amphp/pipeline/tree/v1.2.3" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-03-16T16:33:53+00:00" + }, + { + "name": "amphp/process", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/amphp/process.git", + "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/process/zipball/52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", + "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Process\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A fiber-aware process manager based on Amp and Revolt.", + "homepage": "https://amphp.org/process", + "support": { + "issues": "https://github.com/amphp/process/issues", + "source": "https://github.com/amphp/process/tree/v2.0.3" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-19T03:13:44+00:00" + }, + { + "name": "amphp/serialization", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/serialization.git", + "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/serialization/zipball/693e77b2fb0b266c3c7d622317f881de44ae94a1", + "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "phpunit/phpunit": "^9 || ^8 || ^7" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Serialization\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Serialization tools for IPC and data storage in PHP.", + "homepage": "https://github.com/amphp/serialization", + "keywords": [ + "async", + "asynchronous", + "serialization", + "serialize" + ], + "support": { + "issues": "https://github.com/amphp/serialization/issues", + "source": "https://github.com/amphp/serialization/tree/master" + }, + "time": "2020-03-25T21:39:07+00:00" + }, + { + "name": "amphp/socket", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/socket.git", + "reference": "58e0422221825b79681b72c50c47a930be7bf1e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/socket/zipball/58e0422221825b79681b72c50c47a930be7bf1e1", + "reference": "58e0422221825b79681b72c50c47a930be7bf1e1", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/dns": "^2", + "ext-openssl": "*", + "kelunik/certificate": "^1.1", + "league/uri": "^6.5 | ^7", + "league/uri-interfaces": "^2.3 | ^7", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "amphp/process": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "5.20" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php", + "src/Internal/functions.php", + "src/SocketAddress/functions.php" + ], + "psr-4": { + "Amp\\Socket\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@gmail.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Non-blocking socket connection / server implementations based on Amp and Revolt.", + "homepage": "https://github.com/amphp/socket", + "keywords": [ + "amp", + "async", + "encryption", + "non-blocking", + "sockets", + "tcp", + "tls" + ], + "support": { + "issues": "https://github.com/amphp/socket/issues", + "source": "https://github.com/amphp/socket/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-21T14:33:03+00:00" + }, + { + "name": "amphp/sync", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/sync.git", + "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/sync/zipball/217097b785130d77cfcc58ff583cf26cd1770bf1", + "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/pipeline": "^1", + "amphp/serialization": "^1", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "5.23" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Sync\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" + } + ], + "description": "Non-blocking synchronization primitives for PHP based on Amp and Revolt.", + "homepage": "https://github.com/amphp/sync", + "keywords": [ + "async", + "asynchronous", + "mutex", + "semaphore", + "synchronization" + ], + "support": { + "issues": "https://github.com/amphp/sync/issues", + "source": "https://github.com/amphp/sync/tree/v2.3.0" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-08-03T19:31:26+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.3", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" + }, + "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": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "danog/advanced-json-rpc", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/danog/php-advanced-json-rpc.git", + "reference": "aadb1c4068a88c3d0530cfe324b067920661efcb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/danog/php-advanced-json-rpc/zipball/aadb1c4068a88c3d0530cfe324b067920661efcb", + "reference": "aadb1c4068a88c3d0530cfe324b067920661efcb", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^5", + "php": ">=8.1", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "replace": { + "felixfbecker/php-advanced-json-rpc": "^3" + }, + "require-dev": { + "phpunit/phpunit": "^9" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + }, + { + "name": "Daniil Gentili", + "email": "daniil@daniil.it" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/danog/php-advanced-json-rpc/issues", + "source": "https://github.com/danog/php-advanced-json-rpc/tree/v3.2.2" + }, + "time": "2025-02-14T10:55:15+00:00" + }, + { + "name": "daverandom/libdns", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/DaveRandom/LibDNS.git", + "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DaveRandom/LibDNS/zipball/b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", + "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "Required for IDN support" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "LibDNS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "DNS protocol implementation written in pure PHP", + "keywords": [ + "dns" + ], + "support": { + "issues": "https://github.com/DaveRandom/LibDNS/issues", + "source": "https://github.com/DaveRandom/LibDNS/tree/v2.1.0" + }, + "time": "2024-04-12T12:12:48+00:00" + }, + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "4be43904336affa5c2f70744a348312336afd0da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", + "reference": "4be43904336affa5c2f70744a348312336afd0da", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "ext-json": "*", + "ext-zip": "*", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "source": "https://github.com/PHPCSStandards/composer-installer" + }, + "time": "2023-01-05T11:28:13+00:00" + }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, + "time": "2019-12-04T15:06:13+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=13" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^12 || ^13", + "phpstan/phpstan": "1.4.10 || 2.1.11", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", + "psr/log": "^1 || ^2 || ^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.5" + }, + "time": "2025-04-07T20:06:18+00:00" + }, + { + "name": "felixfbecker/language-server-protocol", + "version": "v1.5.3", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-language-server-protocol.git", + "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/a9e113dbc7d849e35b8776da39edaf4313b7b6c9", + "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpstan/phpstan": "*", + "squizlabs/php_codesniffer": "^3.1", + "vimeo/psalm": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "LanguageServerProtocol\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "PHP classes for the Language Server Protocol", + "keywords": [ + "language", + "microsoft", + "php", + "server" + ], + "support": { + "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", + "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.3" + }, + "time": "2024-04-30T00:40:11+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^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", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-08-06T10:04:20+00:00" + }, + { + "name": "kelunik/certificate", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/kelunik/certificate.git", + "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kelunik/certificate/zipball/7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "php": ">=7.0" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^6 | 7 | ^8 | ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Kelunik\\Certificate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Access certificate details and transform between different formats.", + "keywords": [ + "DER", + "certificate", + "certificates", + "openssl", + "pem", + "x509" + ], + "support": { + "issues": "https://github.com/kelunik/certificate/issues", + "source": "https://github.com/kelunik/certificate/tree/v1.1.3" + }, + "time": "2023-02-03T21:26:53+00:00" + }, + { + "name": "laminas/laminas-coding-standard", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-coding-standard.git", + "reference": "d4412caba9ed16c93cdcf301759f5ee71f9d9aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/d4412caba9ed16c93cdcf301759f5ee71f9d9aea", + "reference": "d4412caba9ed16c93cdcf301759f5ee71f9d9aea", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.0", + "php": "^7.4 || ^8.0", + "slevomat/coding-standard": "^8.15.0", + "squizlabs/php_codesniffer": "^3.10", + "webimpress/coding-standard": "^1.3" + }, + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "LaminasCodingStandard\\": "src/LaminasCodingStandard/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Laminas Coding Standard", + "homepage": "https://laminas.dev", + "keywords": [ + "Coding Standard", + "laminas" + ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-coding-standard/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-coding-standard/issues", + "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", + "source": "https://github.com/laminas/laminas-coding-standard" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2025-05-13T08:37:04+00:00" + }, + { + "name": "league/uri", + "version": "7.5.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "81fb5145d2644324614cc532b28efd0215bda430" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", + "reference": "81fb5145d2644324614cc532b28efd0215bda430", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.5", + "php": "^8.1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", + "league/uri-components": "Needed to easily manipulate URI objects components", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.5.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-12-08T08:40:02+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-factory": "^1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common interfaces and classes for URI representation and interaction", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-12-08T08:18:47+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c", + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-04-29T12:36:36+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v5.0.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c", + "reference": "8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/v5.0.0" + }, + "time": "2024-09-08T10:20:00+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.6.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "92dde6a5919e34835c506ac8c523ef095a95ed62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/92dde6a5919e34835c506ac8c523ef095a95ed62", + "reference": "92dde6a5919e34835c506ac8c523ef095a95ed62", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.1", + "ext-filter": "*", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.2" + }, + "time": "2025-04-13T19:20:35+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.18|^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" + }, + "time": "2024-11-09T15:12:26+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/9b30d6fd026b2c132b3985ce6b23bec09ab3aa68", + "reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.1.0" + }, + "time": "2025-02-19T13:28:12+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/14d63fbcca18457e49c6f8bebaa91a87e8e188d7", + "reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.4.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^11.5.2" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.9" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-25T13:26:39+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-27T05:02:59+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.5.21", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "d565e2cdc21a7db9dc6c399c1fc2083b8010f289" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d565e2cdc21a7db9dc6c399c1fc2083b8010f289", + "reference": "d565e2cdc21a7db9dc6c399c1fc2083b8010f289", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.9", + "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.3", + "sebastian/comparator": "^6.3.1", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.1", + "sebastian/exporter": "^6.3.0", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.2", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.21" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2025-05-21T12:35:00+00:00" + }, + { + "name": "psalm/plugin-phpunit", + "version": "0.19.5", + "source": { + "type": "git", + "url": "https://github.com/psalm/psalm-plugin-phpunit.git", + "reference": "143f9d5e049fffcdbc0da3fbb99f6149f9d3e2dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/143f9d5e049fffcdbc0da3fbb99f6149f9d3e2dc", + "reference": "143f9d5e049fffcdbc0da3fbb99f6149f9d3e2dc", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "php": ">=8.1", + "vimeo/psalm": "dev-master || ^6.10.0" + }, + "conflict": { + "phpspec/prophecy": "<1.20.0", + "phpspec/prophecy-phpunit": "<2.3.0", + "phpunit/phpunit": "<8.5.1" + }, + "require-dev": { + "php": "^7.3 || ^8.0", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "squizlabs/php_codesniffer": "^3.3.1", + "weirdan/prophecy-shim": "^1.0 || ^2.0" + }, + "type": "psalm-plugin", + "extra": { + "psalm": { + "pluginClass": "Psalm\\PhpUnitPlugin\\Plugin" + } + }, + "autoload": { + "psr-4": { + "Psalm\\PhpUnitPlugin\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Brown", + "email": "github@muglug.com" + } + ], + "description": "Psalm plugin for PHPUnit", + "support": { + "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues", + "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.19.5" + }, + "time": "2025-03-31T18:49:55+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "revolt/event-loop", + "version": "v1.0.7", + "source": { + "type": "git", + "url": "https://github.com/revoltphp/event-loop.git", + "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/09bf1bf7f7f574453efe43044b06fafe12216eb3", + "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Revolt\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "ceesjank@gmail.com" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Rock-solid event loop for concurrent PHP applications.", + "keywords": [ + "async", + "asynchronous", + "concurrency", + "event", + "event-loop", + "non-blocking", + "scheduler" + ], + "support": { + "issues": "https://github.com/revoltphp/event-loop/issues", + "source": "https://github.com/revoltphp/event-loop/tree/v1.0.7" + }, + "time": "2025-01-25T19:27:39+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.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "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.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-03-19T07:56:08+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.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/24b8fbc2c8e201bb1308e7b05148d6ab393b6959", + "reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959", + "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.3-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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-03-07T06:57:01+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.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" + } + ], + "time": "2025-05-21T11:55:47+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" + ], + "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.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", + "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", + "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.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-03-18T13:35:50+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": "slevomat/coding-standard", + "version": "8.18.1", + "source": { + "type": "git", + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "06b18b3f64979ab31d27c37021838439f3ed5919" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/06b18b3f64979ab31d27c37021838439f3ed5919", + "reference": "06b18b3f64979ab31d27c37021838439f3ed5919", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", + "php": "^7.4 || ^8.0", + "phpstan/phpdoc-parser": "^2.1.0", + "squizlabs/php_codesniffer": "^3.13.0" + }, + "require-dev": { + "phing/phing": "3.0.1", + "php-parallel-lint/php-parallel-lint": "1.4.0", + "phpstan/phpstan": "2.1.17", + "phpstan/phpstan-deprecation-rules": "2.0.3", + "phpstan/phpstan-phpunit": "2.0.6", + "phpstan/phpstan-strict-rules": "2.0.4", + "phpunit/phpunit": "9.6.8|10.5.45|11.4.4|11.5.21|12.1.3" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-master": "8.x-dev" + } + }, + "autoload": { + "psr-4": { + "SlevomatCodingStandard\\": "SlevomatCodingStandard/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "keywords": [ + "dev", + "phpcs" + ], + "support": { + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/8.18.1" + }, + "funding": [ + { + "url": "https://github.com/kukulich", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", + "type": "tidelift" + } + ], + "time": "2025-05-22T14:32:30+00:00" + }, + { + "name": "spatie/array-to-xml", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/array-to-xml.git", + "reference": "7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67", + "reference": "7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "pestphp/pest": "^1.21", + "spatie/pest-plugin-snapshots": "^1.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Spatie\\ArrayToXml\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://freek.dev", + "role": "Developer" + } + ], + "description": "Convert an array to xml", + "homepage": "https://github.com/spatie/array-to-xml", + "keywords": [ + "array", + "convert", + "xml" + ], + "support": { + "source": "https://github.com/spatie/array-to-xml/tree/3.4.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-12-16T12:45:15+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.13.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "65ff2489553b83b4597e89c3b8b721487011d186" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/65ff2489553b83b4597e89c3b8b721487011d186", + "reference": "65ff2489553b83b4597e89c3b8b721487011d186", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" + }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" + } + ], + "time": "2025-05-11T03:36:00+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.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218", + "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218", + "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.6" + }, + "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": "2025-04-07T19:09:28+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "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": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.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/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/polyfill-ctype", + "version": "v1.32.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.32.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.32.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": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.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-normalizer", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "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\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "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 Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.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-mbstring", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "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.32.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-12-23T08:48:59+00:00" + }, + { + "name": "symfony/polyfill-php84", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "000df7860439609837bbe28670b0be15783b7fbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/000df7860439609837bbe28670b0be15783b7fbf", + "reference": "000df7860439609837bbe28670b0be15783b7fbf", + "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\\Php84\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "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 backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php84/tree/v1.32.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": "2025-02-20T12:04:08+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "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 writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.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": "2025-04-25T09:37:31+00:00" + }, + { + "name": "symfony/string", + "version": "v7.2.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931", + "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/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": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "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": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.2.6" + }, + "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": "2025-04-20T20:18:16+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "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" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" + }, + { + "name": "vimeo/psalm", + "version": "6.11.0", + "source": { + "type": "git", + "url": "https://github.com/vimeo/psalm.git", + "reference": "4ed53b7ccebc09ef60ec4c9e464bf8a01bfd35b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/4ed53b7ccebc09ef60ec4c9e464bf8a01bfd35b0", + "reference": "4ed53b7ccebc09ef60ec4c9e464bf8a01bfd35b0", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/parallel": "^2.3", + "composer-runtime-api": "^2", + "composer/semver": "^1.4 || ^2.0 || ^3.0", + "composer/xdebug-handler": "^2.0 || ^3.0", + "danog/advanced-json-rpc": "^3.1", + "dnoegel/php-xdg-base-dir": "^0.1.1", + "ext-ctype": "*", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "felixfbecker/language-server-protocol": "^1.5.3", + "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0", + "netresearch/jsonmapper": "^5.0", + "nikic/php-parser": "^5.0.0", + "php": "~8.1.31 || ~8.2.27 || ~8.3.16 || ~8.4.3", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0 || ^7.0", + "spatie/array-to-xml": "^2.17.0 || ^3.0", + "symfony/console": "^6.0 || ^7.0", + "symfony/filesystem": "~6.3.12 || ~6.4.3 || ^7.0.3", + "symfony/polyfill-php84": "^1.31.0" + }, + "provide": { + "psalm/psalm": "self.version" + }, + "require-dev": { + "amphp/phpunit-util": "^3", + "bamarni/composer-bin-plugin": "^1.4", + "brianium/paratest": "^6.9", + "danog/class-finder": "^0.4.8", + "dg/bypass-finals": "^1.5", + "ext-curl": "*", + "mockery/mockery": "^1.5", + "nunomaduro/mock-final-classes": "^1.1", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpdoc-parser": "^1.6", + "phpunit/phpunit": "^9.6", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.19", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.6", + "symfony/process": "^6.0 || ^7.0" + }, + "suggest": { + "ext-curl": "In order to send data to shepherd", + "ext-igbinary": "^2.0.5 is required, used to serialize caching data" + }, + "bin": [ + "psalm", + "psalm-language-server", + "psalm-plugin", + "psalm-refactor", + "psalm-review", + "psalter" + ], + "type": "project", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev", + "dev-3.x": "3.x-dev", + "dev-4.x": "4.x-dev", + "dev-5.x": "5.x-dev", + "dev-6.x": "6.x-dev", + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psalm\\": "src/Psalm/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Brown" + }, + { + "name": "Daniil Gentili", + "email": "daniil@daniil.it" + } + ], + "description": "A static analysis tool for finding errors in PHP applications", + "keywords": [ + "code", + "inspection", + "php", + "static analysis" + ], + "support": { + "docs": "https://psalm.dev/docs", + "issues": "https://github.com/vimeo/psalm/issues", + "source": "https://github.com/vimeo/psalm" + }, + "time": "2025-05-12T11:30:26+00:00" + }, + { + "name": "webimpress/coding-standard", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/webimpress/coding-standard.git", + "reference": "6f6a1a90bd9e18fc8bee0660dd1d1ce68cf9fc53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webimpress/coding-standard/zipball/6f6a1a90bd9e18fc8bee0660dd1d1ce68cf9fc53", + "reference": "6f6a1a90bd9e18fc8bee0660dd1d1ce68cf9fc53", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0", + "squizlabs/php_codesniffer": "^3.10.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.6.15" + }, + "type": "phpcodesniffer-standard", + "extra": { + "dev-master": "1.2.x-dev", + "dev-develop": "1.3.x-dev" + }, + "autoload": { + "psr-4": { + "WebimpressCodingStandard\\": "src/WebimpressCodingStandard/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "description": "Webimpress Coding Standard", + "keywords": [ + "Coding Standard", + "PSR-2", + "phpcs", + "psr-12", + "webimpress" + ], + "support": { + "issues": "https://github.com/webimpress/coding-standard/issues", + "source": "https://github.com/webimpress/coding-standard/tree/1.4.0" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } + ], + "time": "2024-10-16T06:55:17+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "laminas/laminas-db": 20 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "ext-pdo": "*", + "ext-pdo_pgsql": "*" + }, + "platform-dev": {}, + "platform-overrides": { + "php": "8.2.99" + }, + "plugin-api-version": "2.6.0" +} diff --git a/coveralls.yml b/coveralls.yml new file mode 100644 index 0000000..bc71b62 --- /dev/null +++ b/coveralls.yml @@ -0,0 +1,2 @@ +coverage_clover: clover.xml +json_path: coveralls-upload.json diff --git a/docker/databases/pgsql/Dockerfile b/docker/databases/pgsql/Dockerfile new file mode 100644 index 0000000..69c3f20 --- /dev/null +++ b/docker/databases/pgsql/Dockerfile @@ -0,0 +1,3 @@ +ARG VERSION=8.4.5 + +FROM mysql:${VERSION}-bookworm AS base \ No newline at end of file diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile new file mode 100644 index 0000000..eaaff2e --- /dev/null +++ b/docker/php/Dockerfile @@ -0,0 +1,26 @@ +ARG PHP_VERSION=8.3.19 + +FROM php:${PHP_VERSION}-apache-bookworm AS base + +# Copy Composer from the official Docker Hub repository to the local filesystem +COPY --from=composer:2.8.6 /usr/bin/composer /usr/bin/ + +# Install the database extensions for MySQL, PostgreSQL, and SQLite, their +# dependencies, and any other tools that are required for the environment to be +# used fully and completely. +RUN apt-get update \ + && apt-get install -y git \ + && docker-php-ext-install mysqli pdo pdo_mysql \ + && apt-get clean + +# Allow the www-data login so that it can run Composer instead of using root +RUN usermod -s /usr/bin/bash www-data + +# Copy all of the files from the context to the current directory setting the +# correct owner +COPY --chown=www-data:www-data . . + +RUN chmod +x bin/install-deps.sh + +# Validate and install PHP's dependencies +RUN su --preserve-environment www-data --command "bin/install-deps.sh" \ No newline at end of file diff --git a/docker/php/conf.d/error_reporting.ini b/docker/php/conf.d/error_reporting.ini new file mode 100644 index 0000000..d040e65 --- /dev/null +++ b/docker/php/conf.d/error_reporting.ini @@ -0,0 +1 @@ +error_reporting=E_ALL \ No newline at end of file diff --git a/docker/php/conf.d/xdebug.ini b/docker/php/conf.d/xdebug.ini new file mode 100644 index 0000000..e29c8bd --- /dev/null +++ b/docker/php/conf.d/xdebug.ini @@ -0,0 +1,6 @@ +zend_extension=xdebug + +[xdebug] +xdebug.mode=develop,debug +xdebug.client_host=host.docker.internal +xdebug.start_with_request=yes \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..d974467 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,37 @@ + + + + + test/unit + + + + + + + + src + + + test/config + test/resource + + + \ No newline at end of file diff --git a/psalm-baseline.xml b/psalm-baseline.xml new file mode 100644 index 0000000..94fc6ab --- /dev/null +++ b/psalm-baseline.xml @@ -0,0 +1,1063 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + has(ProfilerInterface::class) ? $container->get(ProfilerInterface::class) : null]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + resource : $resultResource]]> + + + + resource->insert_id]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + resource->connect_error]]> + + + + + + + + + + + + + resource instanceof \mysqli]]> + resource instanceof \mysqli]]> + + + + resource->connect_error]]> + + + + + + + + + + + + + + + + + + + connection->getResource()]]> + + + + + + + + + + + + + + + + + + + + + + + + + + get('config')['db']]]> + + + + + + + + + + + + + + + + resource->affected_rows]]> + resource->num_rows]]> + resource->num_rows]]> + + + + + + + + + + + + + resource->error]]> + statementBindValues['keys']]]> + + + statementBindValues['keys'][$i]]]> + statementBindValues['values'][$i]]]> + + + currentData[$this->statementBindValues['keys'][$i]]]]> + + + currentData[$this->statementBindValues['keys'][$i]]]]> + + + + + + + + + + + + name]]> + + + resource->num_rows]]> + + + + + + + + + + + + + + + resource->error]]> + resource->num_rows]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + profiler]]> + + + profiler]]> + + + + + + + + + driver]]> + + + + + + + + + + + + + + + + + + + + + + connectionParameters]]> + connectionParameters]]> + + + + + + + + + driver->createStatement($sql)]]> + + + + + + + + + resource->getAttribute(\PDO::ATTR_DRIVER_NAME)]]> + resource->getAttribute(\PDO::ATTR_DRIVER_NAME)]]> + + + + + + + + dsn]]> + + + + + + + fetchColumn()]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + resource]]> + + + + + + + + + + + + + + + + + + + + connection->getResource()]]> + + + + + + + + + + + + + + + + + + + + features[$name]]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + get('config')['db']]]> + + + get('config')['db']]]> + + + + + + + + rowCount instanceof Closure]]> + rowCount)]]> + + + + resource->rowCount()]]> + rowCount)]]> + + + + + + + + + + + + + + + + rowCount;]]> + + + + + + + + + + resource->rowCount()]]> + + + + + + + + + + + resource]]> + + + + + + driver->createResult($this->resource, $this)]]> + + + + + + + + + + + + + + + resource->errorInfo()]]> + + + + + + + + + + + + + + + + + + + + + + + + profiler]]> + + + parameterContainer]]> + profiler]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + processInfo['paramPrefix']]]> + processInfo['paramPrefix']]]> + + + limit]]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + variables]]> + variables]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + adapter]]> + adapter]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + adapter]]> + + + + + + + + + + + + + + + + + + + + + current()]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $key]]> + $key]]> + id]]> + name]]> + value]]> + + + + + + adapter]]> + adapter]]> + adapter]]> + adapter]]> + adapter]]> + adapter]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fixtureFile)]]> + + + + + + + + + + + + + + + + + + + + + + + diff --git a/psalm.xml.dist b/psalm.xml.dist new file mode 100644 index 0000000..86d649b --- /dev/null +++ b/psalm.xml.dist @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/psr-container.php.stub b/psr-container.php.stub new file mode 100644 index 0000000..1a59597 --- /dev/null +++ b/psr-container.php.stub @@ -0,0 +1,23 @@ + $id + * @psalm-return ($id is class-string ? T : mixed) + */ + public function get(string $id): mixed; + } +} \ No newline at end of file diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..580e320 --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "local>axleus/.github:renovate-config" + ] +} \ No newline at end of file diff --git a/src/Adapter.php b/src/Adapter.php new file mode 100644 index 0000000..38e6a53 --- /dev/null +++ b/src/Adapter.php @@ -0,0 +1,17 @@ +has(ResultSetInterface::class) ? $container->get(ResultSetInterface::class) : null; + $profiler = $this->createProfiler($container, $config['db']['profiler'] ?? []); + + return new Adapter( + $container->get(DriverInterface::class), + $container->get(Platform\Postgresql::class), + $resultSetPrototype, + $profiler + ); + } +} \ No newline at end of file diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php new file mode 100644 index 0000000..3e6384f --- /dev/null +++ b/src/ConfigProvider.php @@ -0,0 +1,32 @@ + $this->getDependencies(), + ]; + } + + public function getDependencies(): array + { + return [ + 'aliases' => [ + PlatformInterface::class => Platform\Postgresql::class, + ], + 'factories' => [ + AdapterInterface::class => AdapterServiceFactory::class, + DriverInterface::class => Driver\Pdo\DriverFactory::class, + Platform\Postgresql::class => InvokableFactory::class, + ], + ]; + } +} \ No newline at end of file diff --git a/src/Driver/DatabasePlatformNameTrait.php b/src/Driver/DatabasePlatformNameTrait.php new file mode 100644 index 0000000..5358369 --- /dev/null +++ b/src/Driver/DatabasePlatformNameTrait.php @@ -0,0 +1,23 @@ +setConnectionParameters($connectionParameters); + } elseif ($connectionParameters instanceof PDO) { + $this->setResource($connectionParameters); + } elseif (null !== $connectionParameters) { + throw new Exception\InvalidArgumentException( + '$connection must be an array of parameters, a PDO object or null' + ); + } + } + + /** + * Set driver + * + * @return $this Provides a fluent interface + */ + public function setDriver(PdoDriverInterface $driver): static + { + $this->driver = $driver; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function getCurrentSchema(): bool|string + { + if (! $this->isConnected()) { + $this->connect(); + } + + /** @var PDOStatement $result */ + $result = $this->resource->query('main'); + if ($result instanceof PDOStatement) { + return $result->fetchColumn(); + } + + return false; + } + + /** + * {@inheritDoc} + * @throws Exception\InvalidConnectionParametersException + * @throws Exception\RuntimeException + */ + public function connect(): static + { + if ($this->resource) { + return $this; + } + + $dsn = $username = $password = $hostname = $database = null; + $options = []; + foreach ($this->connectionParameters as $key => $value) { + switch (strtolower($key)) { + case 'dsn': + $dsn = $value; + break; + case 'driver': + $value = strtolower((string) $value); + if (str_starts_with($value, 'pdo')) { + $pdoDriver = str_replace(['-', '_', ' '], '', $value); + $pdoDriver = substr($pdoDriver, 3) ?: ''; + } + break; + case 'pdodriver': + $pdoDriver = (string) $value; + break; + case 'user': + case 'username': + $username = (string) $value; + break; + case 'pass': + case 'password': + $password = (string) $value; + break; + case 'host': + case 'hostname': + $hostname = (string) $value; + break; + case 'database': + case 'dbname': + $database = (string) $value; + break; + case 'unix_socket': + $unixSocket = (string) $value; + break; + case 'driver_options': + case 'options': + $value = (array) $value; + $options = array_diff_key($options, $value) + $value; + break; + default: + $options[$key] = $value; + break; + } + } + + if (isset($hostname) && isset($unixSocket)) { + throw new Exception\InvalidConnectionParametersException( + 'Ambiguous connection parameters, both hostname and unix_socket parameters were set', + $this->connectionParameters + ); + } + + if (! isset($dsn) && isset($pdoDriver)) { + $dsn = $pdoDriver . ':' . $database; + } elseif (! isset($dsn)) { + throw new Exception\InvalidConnectionParametersException( + 'A dsn was not provided or could not be constructed from your parameters', + $this->connectionParameters + ); + } + + $this->dsn = $dsn; + + try { + $this->resource = new PDO($dsn, $username, $password, $options); + $this->resource->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->driverName = strtolower($this->resource->getAttribute(PDO::ATTR_DRIVER_NAME)); + } catch (PDOException $e) { + $code = $e->getCode(); + if (! is_int($code)) { + $code = 0; + } + throw new Exception\RuntimeException('Connect Error: ' . $e->getMessage(), $code, $e); + } + + return $this; + } + + /** + * {@inheritDoc} + */ + public function isConnected(): bool + { + return $this->resource instanceof PDO; + } + + /** + * {@inheritDoc} + */ + public function beginTransaction(): static + { + if (! $this->isConnected()) { + $this->connect(); + } + + if (0 === $this->nestedTransactionsCount) { + $this->resource->beginTransaction(); + $this->inTransaction = true; + } + + $this->nestedTransactionsCount++; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function commit(): static + { + if (! $this->isConnected()) { + $this->connect(); + } + + if ($this->inTransaction) { + $this->nestedTransactionsCount -= 1; + } + + /* + * This shouldn't check for being in a transaction since + * after issuing a SET autocommit=0; we have to commit too. + */ + if (0 === $this->nestedTransactionsCount) { + $this->resource->commit(); + $this->inTransaction = false; + } + + return $this; + } + + /** + * {@inheritDoc} + * @throws Exception\RuntimeException + */ + public function rollback(): static + { + if (! $this->isConnected()) { + throw new Exception\RuntimeException('Must be connected before you can rollback'); + } + + if (! $this->inTransaction()) { + throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback'); + } + + $this->resource->rollBack(); + + $this->inTransaction = false; + $this->nestedTransactionsCount = 0; + + return $this; + } + + /** + * {@inheritDoc} + * @throws Exception\InvalidQueryException + */ + public function execute($sql): ResultInterface + { + if (! $this->isConnected()) { + $this->connect(); + } + + $this->profiler?->profilerStart($sql); + + $resultResource = $this->resource->query($sql); + + $this->profiler?->profilerFinish(); + + if ($resultResource === false) { + $errorInfo = $this->resource->errorInfo(); + throw new Exception\InvalidQueryException($errorInfo[2]); + } + + return $this->driver->createResult($resultResource, $sql); + } + + /** + * {@inheritDoc} + * @param string $name + * @return string|null|false + */ + public function getLastGeneratedValue($name = null): bool|int|string|null + { + try { + return $this->resource->lastInsertId($name); + } catch (\Exception) { + } + + return false; + } + + /** + * Get the dsn string for this connection + * + * @throws RunTimeException + * @return string + */ + public function getDsn(): string + { + if (! $this->dsn) { + throw new Exception\RuntimeException( + 'The DSN has not been set or constructed from parameters in connect() for this Connection' + ); + } + + return $this->dsn; + } + + /** + * Set resource + * + * @return $this Provides a fluent interface + */ + public function setResource(PDO $resource): static + { + $this->resource = $resource; + $this->driverName = strtolower($this->resource->getAttribute(PDO::ATTR_DRIVER_NAME)); + + return $this; + } + + /** + * Prepare + * + * @param ?string $sql + * @return StatementInterface + */ + public function prepare(?string $sql = null): StatementInterface + { + if (! $this->isConnected()) { + $this->connect(); + } + + return $this->driver->createStatement($sql); + } +} diff --git a/src/Driver/Pdo/DriverFactory.php b/src/Driver/Pdo/DriverFactory.php new file mode 100644 index 0000000..6ff3ec9 --- /dev/null +++ b/src/Driver/Pdo/DriverFactory.php @@ -0,0 +1,17 @@ +get('config')['db']); + } +} diff --git a/src/Driver/Pdo/Pdo.php b/src/Driver/Pdo/Pdo.php new file mode 100644 index 0000000..652407e --- /dev/null +++ b/src/Driver/Pdo/Pdo.php @@ -0,0 +1,85 @@ +statementPrototype = $statementPrototype->setDriver($this); + } + + /** + * Register result prototype + */ + public function registerResultPrototype(ResultInterface $resultPrototype): void + { + $this->resultPrototype = $resultPrototype; + } + + /** + * Setup the default features for Pdo + * + * @return $this Provides a fluent interface + */ + public function setupDefaultFeatures(): static + { + return $this; + } + + /** + * Register connection + * + * @return $this Provides a fluent interface + */ + public function registerConnection(PDOConnection|ConnectionInterface $connection): static + { + $this->connection = $connection->setDriver($this); + + return $this; + } + + #[Override] + /** + * @param resource $resource + * @param mixed $context + * @return \Laminas\Db\Adapter\Driver\Pdo\Result + */ + public function createResult($resource, $context = null): Result + { + $result = clone $this->resultPrototype; + $result->initialize($resource, $this->connection->getLastGeneratedValue()); + + return $result; + } +} diff --git a/src/Driver/Pdo/Result.php b/src/Driver/Pdo/Result.php new file mode 100644 index 0000000..0163d81 --- /dev/null +++ b/src/Driver/Pdo/Result.php @@ -0,0 +1,9 @@ +setConnectionParameters($connectionInfo); + } elseif ($connectionInfo instanceof PgSqlConnection || is_resource($connectionInfo)) { + $this->setResource($connectionInfo); + } + } + + /** + * Set resource + * + * @param PgSqlConnection $resource + * @return $this Provides a fluent interface + */ + public function setResource(PgSqlConnection $resource): static + { + $this->resource = $resource; + + return $this; + } + + /** + * Set driver + * + * @return $this Provides a fluent interface + */ + public function setDriver(Pgsql $driver): static + { + $this->driver = $driver; + + return $this; + } + + /** + * @param int|null $type + * @return $this Provides a fluent interface + */ + public function setType(?int $type): static + { + $invalidConectionType = $type !== PGSQL_CONNECT_FORCE_NEW; + if ($invalidConectionType) { + throw new Exception\InvalidArgumentException( + 'Connection type is not valid. (See: https://php.net/manual/en/function.pg-connect.php)' + ); + } + $this->type = $type; + + return $this; + } + + /** + * {@inheritDoc} + * @return null|string + */ + public function getCurrentSchema(): bool|string + { + if (! $this->isConnected()) { + $this->connect(); + } + + $result = pg_query($this->resource, 'SELECT CURRENT_SCHEMA AS "currentschema"'); + if ($result === false) { + return false; + } + + return pg_fetch_result($result, 0, 'currentschema'); + } + + /** + * {@inheritDoc} + * @throws Exception\RuntimeException On failure. + */ + public function connect(): static + { + if ($this->resource instanceof PgSqlConnection) { + return $this; + } + + $connection = $this->getConnectionString(); + set_error_handler(function ($number, $string) { + throw new Exception\RuntimeException( + self::class . '::connect: Unable to connect to database', + $number ?? 0, + new Exception\ErrorException($string, $number ?? 0) + ); + }); + try { + $this->resource = pg_connect($connection); + } finally { + restore_error_handler(); + } + + if ($this->resource === false) { + throw new Exception\RuntimeException(sprintf( + '%s: Unable to connect to database', + __METHOD__ + )); + } + + if (! empty($this->connectionParameters['charset'])) { + if (pg_set_client_encoding($this->resource, $this->connectionParameters['charset']) === -1) { + throw new Exception\RuntimeException(sprintf( + "%s: Unable to set client encoding '%s'", + __METHOD__, + $this->connectionParameters['charset'] + )); + } + } + + return $this; + } + + /** + * {@inheritDoc} + */ + public function isConnected(): bool + { + return $this->resource instanceof PgSqlConnection; + } + + /** + * {@inheritDoc} + */ + public function disconnect(): static + { + // phpcs:ignore SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFallbackGlobalName + pg_close($this->resource); + + return $this; + } + + /** + * {@inheritDoc} + */ + public function beginTransaction(): static + { + if ($this->inTransaction()) { + throw new Exception\RuntimeException('Nested transactions are not supported'); + } + + if (! $this->isConnected()) { + $this->connect(); + } + + pg_query($this->resource, 'BEGIN'); + $this->inTransaction = true; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function commit(): static + { + if (! $this->isConnected()) { + $this->connect(); + } + + if (! $this->inTransaction()) { + return $this; // We ignore attempts to commit non-existing transaction + } + + pg_query($this->resource, 'COMMIT'); + $this->inTransaction = false; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function rollback(): static + { + if (! $this->isConnected()) { + throw new Exception\RuntimeException('Must be connected before you can rollback'); + } + + if (! $this->inTransaction()) { + throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback'); + } + + pg_query($this->resource, 'ROLLBACK'); + $this->inTransaction = false; + + return $this; + } + + /** + * {@inheritDoc} + * @throws Exception\InvalidQueryException + * @return resource|ResultSetInterface + */ + public function execute($sql): ResultInterface + { + if (! $this->isConnected()) { + $this->connect(); + } + + $this->profiler?->profilerStart($sql); + + $resultResource = pg_query($this->resource, $sql); + + $this->profiler?->profilerFinish(); + + // if the returnValue is something other than a pg result resource, bypass wrapping it + if ($resultResource === false) { + throw new Exception\InvalidQueryException(pg_last_error($this->resource)); + } + + return $this->driver->createResult($resultResource); + } + + /** + * {@inheritDoc} + * @return string + */ + public function getLastGeneratedValue($name = null): bool|int|string|null + { + if ($name === null) { + return null; + } + $result = pg_query( + $this->resource, + 'SELECT CURRVAL(\'' . str_replace('\'', '\\\'', $name) . '\') as "currval"' + ); + + return pg_fetch_result($result, 0, 'currval'); + } + + /** + * Get Connection String + * + * @return string + */ + private function getConnectionString(): string + { + $connectionParameters = array_filter((new PgsqlConfig())($this->connectionParameters)); + + return urldecode(http_build_query($connectionParameters, '', ' ')); + } +} diff --git a/src/Driver/Pgsql/Pgsql.php b/src/Driver/Pgsql/Pgsql.php new file mode 100644 index 0000000..9c155f6 --- /dev/null +++ b/src/Driver/Pgsql/Pgsql.php @@ -0,0 +1,223 @@ + false, + ]; + + /** + * Constructor + * + * @param array|Connection|resource $connection + * @param array $options + */ + public function __construct( + $connection, + ?Statement $statementPrototype = null, + ?Result $resultPrototype = null, + $options = null + ) { + if (! $connection instanceof Connection) { + $connection = new Connection($connection); + } + + $this->registerConnection($connection); + $this->registerStatementPrototype($statementPrototype ?: new Statement()); + $this->registerResultPrototype($resultPrototype ?: new Result()); + } + + /** + * @return $this Provides a fluent interface + */ + public function setProfiler(Profiler\ProfilerInterface $profiler): static + { + $this->profiler = $profiler; + + if ($this->connection instanceof Profiler\ProfilerAwareInterface) { + $this->connection->setProfiler($profiler); + } + + if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) { + $this->statementPrototype->setProfiler($profiler); + } + + return $this; + } + + /** + * @return null|Profiler\ProfilerInterface + */ + public function getProfiler() + { + return $this->profiler; + } + + /** + * Register connection + * + * @return $this Provides a fluent interface + */ + public function registerConnection(Connection $connection) + { + $this->connection = $connection; + $this->connection->setDriver($this); + + return $this; + } + + /** + * Register statement prototype + * + * @return $this Provides a fluent interface + */ + public function registerStatementPrototype(Statement $statement) + { + $this->statementPrototype = $statement; + $this->statementPrototype->setDriver($this); // needs access to driver to createResult() + + return $this; + } + + /** + * Register result prototype + * + * @return $this Provides a fluent interface + */ + public function registerResultPrototype(Result $result) + { + $this->resultPrototype = $result; + + return $this; + } + + /** + * Check environment + * + * @throws Exception\RuntimeException + * @return void + */ + public function checkEnvironment() + { + if (! extension_loaded('pgsql')) { + throw new Exception\RuntimeException( + 'The PostgreSQL (pgsql) extension is required for this adapter but the extension is not loaded' + ); + } + } + + /** + * Get connection + * + * @return Connection + */ + public function getConnection() + { + return $this->connection; + } + + /** + * Create statement + * + * @param string|null $sqlOrResource + * @return Statement + */ + public function createStatement($sqlOrResource = null) + { + $statement = clone $this->statementPrototype; + + if (is_string($sqlOrResource)) { + $statement->setSql($sqlOrResource); + } + + if (! $this->connection->isConnected()) { + $this->connection->connect(); + } + + $statement->initialize($this->connection->getResource()); + + return $statement; + } + + /** + * Create result + * + * @param PgSqlResult|PgSqlConnection $resource + * @return Result + */ + public function createResult($resource) + { + $result = clone $this->resultPrototype; + $result->initialize($resource, $this->connection->getLastGeneratedValue()); + + return $result; + } + + /** + * @return Result + */ + public function getResultPrototype() + { + return $this->resultPrototype; + } + + /** + * Get prepare Type + * + * @return string + */ + public function getPrepareType() + { + return self::PARAMETERIZATION_POSITIONAL; + } + + /** + * Format parameter name + * + * @param string $name + * @param mixed $type + * @return string + */ + public function formatParameterName($name, $type = null) + { + return '$#'; + } + + /** + * Get last generated value + * + * @param string $name + * @return mixed + */ + public function getLastGeneratedValue($name = null) + { + return $this->connection->getLastGeneratedValue($name); + } +} diff --git a/src/Driver/Pgsql/PgsqlConfig.php b/src/Driver/Pgsql/PgsqlConfig.php new file mode 100644 index 0000000..f8648f1 --- /dev/null +++ b/src/Driver/Pgsql/PgsqlConfig.php @@ -0,0 +1,56 @@ + $value) { + $name = match (strtolower($name)) { + 'host', 'hostname' => 'host', + 'user', 'username' => 'user', + 'password', 'passwd', 'pw' => 'password', + 'database', 'dbname', 'db', 'schema' => 'dbname', + 'port' => 'port', + 'socket' => 'socket', + default => throw new InvalidArgumentException( + 'Unknown connection parameter "' . $name . '"' + ), + }; + $connectionParameters[$name] = $value; + } + + $connectionFilters = [ + 'host' => [ + 'filter' => FILTER_SANITIZE_URL, + 'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_EMPTY_STRING_NULL, + ], + 'user' => [ + 'filter' => FILTER_SANITIZE_ENCODED, + 'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_EMPTY_STRING_NULL, + ], + 'password' => [ + 'filter' => FILTER_SANITIZE_ENCODED, + 'flags' => FILTER_FLAG_EMPTY_STRING_NULL, + ], + 'database' => [ + 'filter' => FILTER_SANITIZE_ENCODED, + 'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_EMPTY_STRING_NULL, + ], + 'socket' => [ + 'filter' => FILTER_SANITIZE_ENCODED, + 'flags' => FILTER_FLAG_EMPTY_STRING_NULL, + ], + 'port' => [ + 'filter' => FILTER_VALIDATE_INT, + 'flags' => FILTER_NULL_ON_FAILURE, + ], + ]; + + return filter_var_array($connectionParameters, $connectionFilters); + } +} \ No newline at end of file diff --git a/src/Driver/Pgsql/Result.php b/src/Driver/Pgsql/Result.php new file mode 100644 index 0000000..d20cdd3 --- /dev/null +++ b/src/Driver/Pgsql/Result.php @@ -0,0 +1,193 @@ +resource = $resource; + $this->count = pg_num_rows($this->resource); + $this->generatedValue = $generatedValue; + } + + /** + * Current + * + * @return array|bool|mixed + */ + #[ReturnTypeWillChange] + public function current() + { + if ($this->count === 0) { + return false; + } + return pg_fetch_assoc($this->resource, $this->position); + } + + /** + * Next + * + * @return void + */ + #[ReturnTypeWillChange] + public function next() + { + $this->position++; + } + + /** + * Key + * + * @return int|mixed + */ + #[ReturnTypeWillChange] + public function key() + { + return $this->position; + } + + /** + * Valid + * + * @return bool + */ + #[ReturnTypeWillChange] + public function valid() + { + return $this->position < $this->count; + } + + /** + * Rewind + * + * @return void + */ + #[ReturnTypeWillChange] + public function rewind() + { + $this->position = 0; + } + + /** + * Buffer + * + * @return null + */ + public function buffer() + { + return null; + } + + /** + * Is buffered + * + * @return false + */ + public function isBuffered() + { + return false; + } + + /** + * Is query result + * + * @return bool + */ + public function isQueryResult() + { + return pg_num_fields($this->resource) > 0; + } + + /** + * Get affected rows + * + * @return int + */ + public function getAffectedRows() + { + return pg_affected_rows($this->resource); + } + + /** + * Get generated value + * + * @return mixed|null + */ + public function getGeneratedValue() + { + return $this->generatedValue; + } + + /** + * Get resource + */ + public function getResource() + { + // TODO: Implement getResource() method. + } + + /** + * Count + * + * @return int The custom count as an integer. + */ + #[ReturnTypeWillChange] + public function count() + { + return $this->count; + } + + /** + * Get field count + * + * @return int + */ + public function getFieldCount() + { + return pg_num_fields($this->resource); + } +} diff --git a/src/Driver/Pgsql/Statement.php b/src/Driver/Pgsql/Statement.php new file mode 100644 index 0000000..4cd78fd --- /dev/null +++ b/src/Driver/Pgsql/Statement.php @@ -0,0 +1,231 @@ +driver = $driver; + return $this; + } + + /** + * @return $this Provides a fluent interface + */ + public function setProfiler(Profiler\ProfilerInterface $profiler): static + { + $this->profiler = $profiler; + return $this; + } + + /** + * @return null|Profiler\ProfilerInterface + */ + public function getProfiler(): ?Profiler\ProfilerInterface + { + return $this->profiler; + } + + /** + * Initialize + * + * @param resource $pgsql + * @return void + * @throws Exception\RuntimeException For invalid or missing postgresql connection. + */ + public function initialize($pgsql): void + { + if ( + ! $pgsql instanceof PgSqlConnection + && ( + ! is_resource($pgsql) + || 'pgsql link' !== get_resource_type($pgsql) + ) + ) { + throw new Exception\RuntimeException(sprintf( + '%s: Invalid or missing postgresql connection; received "%s"', + __METHOD__, + get_resource_type($pgsql) + )); + } + + $this->pgsql = $pgsql; + } + + /** + * Get resource + * + * @todo Implement this method + * phpcs:ignore Squiz.Commenting.FunctionComment.InvalidNoReturn + * @return resource + */ + public function getResource() + { + return $this->resource; + } + + /** + * Set sql + * + * @param string $sql + * @return $this Provides a fluent interface + */ + public function setSql($sql): static + { + $this->sql = $sql; + return $this; + } + + /** + * Get sql + * + * @return string + */ + public function getSql(): ?string + { + return $this->sql; + } + + /** + * Set parameter container + * + * @return $this Provides a fluent interface + */ + public function setParameterContainer(ParameterContainer $parameterContainer): static + { + $this->parameterContainer = $parameterContainer; + return $this; + } + + /** + * Get parameter container + * + * @return ParameterContainer + */ + public function getParameterContainer(): ParameterContainer + { + return $this->parameterContainer; + } + + /** + * Prepare + * + * @param string $sql + */ + public function prepare($sql = null): StatementInterface + { + $sql = $sql ?: $this->sql; + + $pCount = 1; + $sql = preg_replace_callback( + '#\$\##', + function () use (&$pCount) { + return '$' . $pCount++; + }, + $sql + ); + + $this->sql = $sql; + $this->statementName = 'statement' . ++static::$statementIndex; + $this->resource = pg_prepare($this->pgsql, $this->statementName, $sql); + } + + /** + * Is prepared + * + * @return bool + */ + public function isPrepared(): bool + { + return isset($this->resource); + } + + /** + * Execute + * + * @param array|ParameterContainer $parameters + * @throws Exception\InvalidQueryException + * @return Result + */ + public function execute(ParameterContainer|array $parameters = null): ?ResultInterface + { + if (! $this->isPrepared()) { + $this->prepare(); + } + + /** START Standard ParameterContainer Merging Block */ + if (! $this->parameterContainer instanceof ParameterContainer) { + if ($parameters instanceof ParameterContainer) { + $this->parameterContainer = $parameters; + $parameters = null; + } else { + $this->parameterContainer = new ParameterContainer(); + } + } + + if (is_array($parameters)) { + $this->parameterContainer->setFromArray($parameters); + } + + if ($this->parameterContainer->count() > 0) { + $parameters = $this->parameterContainer->getPositionalArray(); + } + /** END Standard ParameterContainer Merging Block */ + + $this->profiler?->profilerStart($this); + + $resultResource = pg_execute($this->pgsql, $this->statementName, (array) $parameters); + + $this->profiler?->profilerFinish(); + + if ($resultResource === false) { + throw new Exception\InvalidQueryException(pg_last_error()); + } + + return $this->driver->createResult($resultResource); + } +} diff --git a/src/Module.php b/src/Module.php new file mode 100644 index 0000000..d69d498 --- /dev/null +++ b/src/Module.php @@ -0,0 +1,15 @@ + (new ConfigProvider())->getDependencies(), + ]; + } +} diff --git a/src/Platform/Postgresql.php b/src/Platform/Postgresql.php new file mode 100644 index 0000000..182c63b --- /dev/null +++ b/src/Platform/Postgresql.php @@ -0,0 +1,142 @@ +setDriver($driver); + } + } + + /** + * @param Pgsql\Pgsql|DriverPdo|resource|PDO $driver + * @throws Exception\InvalidArgumentException + * @return $this Provides a fluent interface + */ + public function setDriver($driver): static + { + if ( + $driver instanceof Pgsql\Pgsql + || ($driver instanceof DriverPdo && $driver->getDatabasePlatformName() === 'Postgresql') + || $driver instanceof PgSqlConnection // PHP 8.1+ + || (is_resource($driver) && in_array(get_resource_type($driver), $this->knownPgsqlResources, true)) + || ($driver instanceof PDO && $driver->getAttribute(PDO::ATTR_DRIVER_NAME) === 'pgsql') + ) { + $this->driver = $driver; + + return $this; + } + + throw new Exception\InvalidArgumentException( + '$driver must be a Pgsql or Postgresql PDO Laminas\Db\Adapter\Driver, pgsql link resource' + . ' or Postgresql PDO instance' + ); + } + + /** + * {@inheritDoc} + */ + public function getName(): string + { + return 'PostgreSQL'; + } + + /** + * {@inheritDoc} + */ + public function quoteIdentifierChain($identifierChain): string + { + return '"' . implode('"."', (array) str_replace('"', '""', $identifierChain)) . '"'; + } + + /** + * {@inheritDoc} + */ + public function quoteValue($value): string + { + $quotedViaDriverValue = $this->quoteViaDriver($value); + + return $quotedViaDriverValue ?? 'E' . parent::quoteValue($value); + } + + /** + * {@inheritDoc} + * @param scalar $value + * @return string + */ + public function quoteTrustedValue($value): string + { + $quotedViaDriverValue = $this->quoteViaDriver($value); + + if ($quotedViaDriverValue === null) { + return 'E' . parent::quoteTrustedValue($value); + } + + return $quotedViaDriverValue; + } + + /** + * @param string $value + * @return string|null + */ + protected function quoteViaDriver($value): ?string + { + $resource = $this->driver instanceof DriverInterface + ? $this->driver->getConnection()->getResource() + : $this->driver; + + if ($resource instanceof PgSqlConnection || is_resource($resource)) { + return '\'' . pg_escape_string($resource, $value) . '\''; + } + + if ($resource instanceof PDO) { + return $resource->quote($value); + } + + return null; + } + + public function getSqlPlatformDecorator(): PlatformDecoratorInterface + { + return new SqlPlatformDecorator($this->driver); + } +} diff --git a/src/test.php b/src/test.php new file mode 100644 index 0000000..988fa72 --- /dev/null +++ b/src/test.php @@ -0,0 +1,20 @@ +markTestSkipped('pdo_pgsql integration tests are not enabled!'); + } + + $this->adapter = new Adapter([ + 'driver' => 'pdo_pgsql', + 'database' => (string) getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE'), + 'hostname' => (string) getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME'), + 'username' => (string) getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_USERNAME'), + 'password' => (string) getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_PASSWORD'), + ]); + + $this->hostname = (string) getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME'); + } +} diff --git a/test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php b/test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php new file mode 100644 index 0000000..b471be2 --- /dev/null +++ b/test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php @@ -0,0 +1,31 @@ +addFeature(new SequenceFeature('id', 'test_seq_id_seq')); + + $tableGateway = new TableGateway($table, $this->getAdapter(), $featureSet); + + $tableGateway->insert(['foo' => 'bar']); + self::assertSame(1, $tableGateway->getLastInsertValue()); + + $tableGateway->insert(['foo' => 'baz']); + self::assertSame(2, $tableGateway->getLastInsertValue()); + } +} diff --git a/test/integration/Adapter/Platform/PostgresqlTest.php b/test/integration/Adapter/Platform/PostgresqlTest.php new file mode 100644 index 0000000..bb4ace0 --- /dev/null +++ b/test/integration/Adapter/Platform/PostgresqlTest.php @@ -0,0 +1,88 @@ + */ + public array|\PDO $adapters = []; + + #[Override] + protected function setUp(): void + { + if (! getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL')) { + $this->markTestSkipped(self::class . ' integration tests are not enabled!'); + } + if (extension_loaded('pgsql')) { + $this->adapters['pgsql'] = pg_connect( + 'host=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME') + . ' dbname=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE') + . ' user=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_USERNAME') + . ' password=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_PASSWORD') + ); + } + if (extension_loaded('pdo')) { + $this->adapters['pdo_pgsql'] = new \PDO( + 'pgsql:host=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME') . ';dbname=' + . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE'), + getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_USERNAME'), + getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_PASSWORD') + ); + } + } + + /** + * @return void + */ + public function testQuoteValueWithPgsql() + { + if ( + ! isset($this->adapters['pgsql']) + || ( + ! $this->adapters['pgsql'] instanceof PgSqlConnection + && ! is_resource($this->adapters['pgsql']) + ) + ) { + $this->markTestSkipped('Postgres (pgsql) not configured in unit test configuration file'); + } + $pgsql = new Postgresql($this->adapters['pgsql']); + $value = $pgsql->quoteValue('value'); + self::assertEquals('\'value\'', $value); + + $pgsql = new Postgresql(new Pgsql\Pgsql(new Pgsql\Connection($this->adapters['pgsql']))); + $value = $pgsql->quoteValue('value'); + self::assertEquals('\'value\'', $value); + } + + /** + * @return void + */ + public function testQuoteValueWithPdoPgsql() + { + if (! isset($this->adapters['pdo_pgsql']) || ! $this->adapters['pdo_pgsql'] instanceof \PDO) { + $this->markTestSkipped('Postgres (PDO_PGSQL) not configured in unit test configuration file'); + } + $pgsql = new Postgresql($this->adapters['pdo_pgsql']); + $value = $pgsql->quoteValue('value'); + self::assertEquals('\'value\'', $value); + + $pgsql = new Postgresql(new Pdo\Pdo(new Pdo\Connection($this->adapters['pdo_pgsql']))); + $value = $pgsql->quoteValue('value'); + self::assertEquals('\'value\'', $value); + } +} diff --git a/test/integration/Platform/PgsqlFixtureLoader.php b/test/integration/Platform/PgsqlFixtureLoader.php new file mode 100644 index 0000000..e82a62f --- /dev/null +++ b/test/integration/Platform/PgsqlFixtureLoader.php @@ -0,0 +1,104 @@ +connect(); + + $this->dropDatabase(); // closes connection + + $this->connect(); + + if ( + false === $this->pdo->exec(sprintf( + "CREATE DATABASE %s", + getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE') + )) + ) { + throw new Exception(sprintf( + "I cannot create the PostgreSQL %s test database: %s", + getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE'), + print_r($this->pdo->errorInfo(), true) + )); + } + + // PostgreSQL cannot switch database on same connection. + $this->disconnect(); + + $this->connect(true); + + if (false === $this->pdo->exec(file_get_contents($this->fixtureFile))) { + throw new Exception(sprintf( + "I cannot create the table for %s database. Check the %s file. %s ", + getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE'), + $this->fixtureFile, + print_r($this->pdo->errorInfo(), true) + )); + } + + $this->disconnect(); + } + + public function dropDatabase(): void + { + if (! $this->initialRun) { + // Not possible to drop in PostgreSQL. + // Connection is locking the database and trying to close it with unset() + // does not trigger garbage collector on time to actually close it to free the lock. + return; + } + $this->initialRun = false; + + $this->connect(); + + $this->pdo->exec(sprintf( + "DROP DATABASE IF EXISTS %s", + getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE') + )); + + $this->disconnect(); + } + + /** + * @param bool $useDb add dbname using in dsn + */ + protected function connect(bool $useDb = false): void + { + $dsn = 'pgsql:host=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME'); + + if ($useDb) { + $dsn .= ';dbname=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE'); + } + + $this->pdo = new PDO( + $dsn, + getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_USERNAME'), + getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_PASSWORD') + ); + } + + protected function disconnect(): void + { + $this->pdo = null; + } +} diff --git a/test/integration/TestFixtures/pgsql.sql b/test/integration/TestFixtures/pgsql.sql new file mode 100644 index 0000000..3fe43cc --- /dev/null +++ b/test/integration/TestFixtures/pgsql.sql @@ -0,0 +1,29 @@ +DROP TABLE IF EXISTS test; +CREATE TABLE IF NOT EXISTS test ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + value VARCHAR(255) NOT NULL +); + +INSERT INTO test (name, value) +VALUES +('foo', 'bar'), +('bar', 'baz'); + +DROP TABLE IF EXISTS test_charset; +CREATE TABLE IF NOT EXISTS test_charset ( + id SERIAL PRIMARY KEY, + field$ VARCHAR(255) NOT NULL, + field_ VARCHAR(255) NOT NULL +); + +INSERT INTO test_charset (field$, field_) +VALUES +('foo', 'bar'), +('bar', 'baz'); + +CREATE TABLE IF NOT EXISTS test_seq ( + id SERIAL, + foo VARCHAR(255) NOT NULL, + CONSTRAINT test_seq_pkey PRIMARY KEY (id) +); diff --git a/test/unit/Adapter/AdapterServiceFactoryTest.php b/test/unit/Adapter/AdapterServiceFactoryTest.php new file mode 100644 index 0000000..2d36ea5 --- /dev/null +++ b/test/unit/Adapter/AdapterServiceFactoryTest.php @@ -0,0 +1,115 @@ +getDependencies(); + $config['services']['config'] = $dbConfig; + + return new ServiceManager($config); + } + + #[Override] + protected function setUp(): void + { + if (! extension_loaded('pdo_sqlite')) { + $this->markTestSkipped('Adapter factory tests require pdo_sqlite'); + } + + $this->factory = new AdapterServiceFactory(); + } + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function testV3FactoryReturnsDefaultAdapter(): void + { + $this->expectNotToPerformAssertions(); + + $services = $this->createServiceManager([ + 'db' => [ + 'driver' => 'Pdo_Pgsql', + 'database' => ':memory:' + ] + ]); + + $this->factory->__invoke($services, Adapter::class); + } + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function testV3FactoryReturnsDefaultAdapterWithDefaultProfiler(): void + { + $services = $this->createServiceManager([ + 'db' => [ + 'driver' => 'Pdo_Pgsql', + 'database' => ':memory:', + 'profiler' => true + ] + ]); + + $adapter = $this->factory->__invoke($services, Adapter::class); + self::assertInstanceOf(ProfilerInterface::class, $adapter->getProfiler()); + } + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function testV3FactoryReturnsDefaultAdapterWithProfilerClassname(): void + { + $services = $this->createServiceManager([ + 'db' => [ + 'driver' => 'Pdo_Pgsql', + 'database' => ':memory:', + 'profiler' => Profiler::class + ] + ]); + + $adapter = $this->factory->__invoke($services, Adapter::class); + self::assertInstanceOf(ProfilerInterface::class, $adapter->getProfiler()); + } + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function testV3FactoryReturnsDefaultAdapterWithProfilerInstance(): void + { + $services = $this->createServiceManager([ + 'db' => [ + 'driver' => 'Pdo_Pgsql', + 'database' => ':memory:', + 'profiler' => $this->getMockBuilder(ProfilerInterface::class)->getMock() + ] + ]); + + $adapter = $this->factory->__invoke($services, Adapter::class); + self::assertInstanceOf(ProfilerInterface::class, $adapter->getProfiler()); + } +} diff --git a/test/unit/Adapter/AdapterTest.php b/test/unit/Adapter/AdapterTest.php new file mode 100644 index 0000000..27188d1 --- /dev/null +++ b/test/unit/Adapter/AdapterTest.php @@ -0,0 +1,261 @@ +adapter->setProfiler(new Profiler\Profiler()); + self::assertSame($this->adapter, $ret); + } + + #[TestDox('unit test: Test getProfiler() will store profiler')] + public function testGetProfiler(): void + { + $this->adapter->setProfiler($profiler = new Profiler\Profiler()); + self::assertSame($profiler, $this->adapter->getProfiler()); + + $adapter = new Adapter(['driver' => $this->mockDriver, 'profiler' => true], $this->mockPlatform); + self::assertInstanceOf(Profiler\Profiler::class, $adapter->getProfiler()); + } + + #[TestDox('unit test: Test createDriverFromParameters() will create proper driver type')] + public function testCreateDriver(): void + { + if (extension_loaded('pdo')) { + $adapter = new Adapter(['driver' => 'pdo_sqlite'], $this->mockPlatform); + self::assertInstanceOf(Pdo::class, $adapter->driver); + unset($adapter); + } + } + + #[TestDox('unit test: Test createPlatformFromDriver() will create proper platform from driver')] + public function testCreatePlatform(): void + { + $driver = clone $this->mockDriver; + $driver->expects($this->any())->method('getDatabasePlatformName')->willReturn('Pgsql'); + $adapter = new Adapter($driver); + self::assertInstanceOf(PgsqlPlatform::class, $adapter->platform); + unset($adapter, $driver); + } + + #[TestDox('unit test: Test getDriver() will return driver object')] + public function testGetDriver(): void + { + self::assertSame($this->mockDriver, $this->adapter->getDriver()); + } + + #[TestDox('unit test: Test getPlatform() returns platform object')] + public function testGetPlatform(): void + { + self::assertSame($this->mockPlatform, $this->adapter->getPlatform()); + } + + #[TestDox('unit test: Test getPlatform() returns platform object')] + public function testGetQueryResultSetPrototype(): void + { + self::assertInstanceOf(ResultSetInterface::class, $this->adapter->getQueryResultSetPrototype()); + } + + #[TestDox('unit test: Test getCurrentSchema() returns current schema from connection object')] + public function testGetCurrentSchema(): void + { + $this->mockConnection->expects($this->any())->method('getCurrentSchema')->willReturn('FooSchema'); + self::assertEquals('FooSchema', $this->adapter->getCurrentSchema()); + } + + /** + * @throws \Exception + */ + #[TestDox('unit test: Test query() in prepare mode produces a statement object')] + public function testQueryWhenPreparedProducesStatement(): void + { + $s = $this->adapter->query('SELECT foo'); + self::assertSame($this->mockStatement, $s); + } + + /** + * @throws Exception + * @throws \Exception + */ + #[Group('#210')] + public function testProducedResultSetPrototypeIsDifferentForEachQuery(): void + { + $statement = $this->createMock(StatementInterface::class); + $result = $this->createMock(ResultInterface::class); + + $this->mockDriver->method('createStatement') + ->willReturn($statement); + $this->mockStatement->method('execute') + ->willReturn($result); + $result->method('isQueryResult') + ->willReturn(true); + + self::assertNotSame( + $this->adapter->query('SELECT foo', []), + $this->adapter->query('SELECT foo', []) + ); + } + + /** + * @throws \Exception + */ + #[TestDox('unit test: Test query() in prepare mode, with array of parameters, produces a result object')] + public function testQueryWhenPreparedWithParameterArrayProducesResult(): void + { + $parray = ['bar' => 'foo']; + $sql = 'SELECT foo, :bar'; + $statement = $this->getMockBuilder(StatementInterface::class)->getMock(); + $result = $this->getMockBuilder(ResultInterface::class)->getMock(); + $this->mockDriver->expects($this->any())->method('createStatement') + ->with($sql)->willReturn($statement); + $this->mockStatement->expects($this->any())->method('execute')->willReturn($result); + + $r = $this->adapter->query($sql, $parray); + self::assertSame($result, $r); + } + + /** + * @throws \Exception + */ + #[TestDox('unit test: Test query() in prepare mode, with ParameterContainer, produces a result object')] + public function testQueryWhenPreparedWithParameterContainerProducesResult(): void + { + $sql = 'SELECT foo'; + $parameterContainer = $this->getMockBuilder(ParameterContainer::class)->getMock(); + $result = $this->getMockBuilder(ResultInterface::class)->getMock(); + $this->mockDriver->expects($this->any())->method('createStatement') + ->with($sql)->willReturn($this->mockStatement); + $this->mockStatement->expects($this->any())->method('execute')->willReturn($result); + $result->expects($this->any())->method('isQueryResult')->willReturn(true); + + $r = $this->adapter->query($sql, $parameterContainer); + self::assertInstanceOf(ResultSet::class, $r); + } + + /** + * @throws \Exception + */ + #[TestDox('unit test: Test query() in execute mode produces a driver result object')] + public function testQueryWhenExecutedProducesAResult(): void + { + $sql = 'SELECT foo'; + $result = $this->getMockBuilder(ResultInterface::class)->getMock(); + $this->mockConnection->expects($this->any())->method('execute')->with($sql)->willReturn($result); + + $r = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); + self::assertSame($result, $r); + } + + /** + * @throws \Exception + */ + #[TestDox('unit test: Test query() in execute mode produces a resultset object')] + public function testQueryWhenExecutedProducesAResultSetObjectWhenResultIsQuery(): void + { + $sql = 'SELECT foo'; + + $result = $this->getMockBuilder(ResultInterface::class)->getMock(); + $this->mockConnection->expects($this->any())->method('execute')->with($sql)->willReturn($result); + $result->expects($this->any())->method('isQueryResult')->willReturn(true); + + $r = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); + self::assertInstanceOf(ResultSet::class, $r); + + $r = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE, new TemporaryResultSet()); + self::assertInstanceOf(TemporaryResultSet::class, $r); + } + + #[TestDox('unit test: Test createStatement() produces a statement object')] + public function testCreateStatement(): void + { + self::assertSame($this->mockStatement, $this->adapter->createStatement()); + } + + public function test__get(): void + { + // @codingStandardsIgnoreEnd + self::assertSame($this->mockDriver, $this->adapter->driver); + /** @psalm-suppress UndefinedMagicPropertyFetch */ + self::assertSame($this->mockDriver, $this->adapter->DrivER); + /** @psalm-suppress UndefinedMagicPropertyFetch */ + self::assertSame($this->mockPlatform, $this->adapter->PlatForm); + self::assertSame($this->mockPlatform, $this->adapter->platform); + + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Invalid magic'); + $this->adapter->foo; + } + + // @codingStandardsIgnoreStart + + /** + * @throws Exception + */ + #[Override] + protected function setUp(): void + { + $this->mockConnection = $this->createMock(ConnectionInterface::class); + $this->mockPlatform = new PgsqlPlatform(); + $this->mockStatement = $this->getMockBuilder(Statement::class)->getMock(); + $this->mockDriver = $this->getMockBuilder(Pdo::class) + ->setConstructorArgs([ + $this->mockConnection, + $this->mockStatement, + ]) + ->getMock(); + + $this->mockDriver->method('getDatabasePlatformName')->willReturn('Pgsql'); + $this->mockDriver->method('checkEnvironment')->willReturn(true); + $this->mockDriver->method('getConnection')->willReturn($this->mockConnection); + $this->mockDriver->method('createStatement')->willReturn($this->mockStatement); + + $this->adapter = new Adapter($this->mockDriver, $this->mockPlatform); + } +} diff --git a/test/unit/Adapter/ConfigProviderTest.php b/test/unit/Adapter/ConfigProviderTest.php new file mode 100644 index 0000000..3c4deb6 --- /dev/null +++ b/test/unit/Adapter/ConfigProviderTest.php @@ -0,0 +1,50 @@ +> */ + private array $config = [ + 'aliases' => [ + PlatformInterface::class => Platform\Pgsql::class, + ProfilerInterface::class => Profiler::class, + ], + 'factories' => [ + AdapterInterface::class => AdapterServiceFactory::class, + DriverInterface::class => Driver\Pdo\DriverFactory::class, + Platform\Pgsql::class => InvokableFactory::class, + Profiler::class => InvokableFactory::class, + ], + ]; + + public function testProvidesExpectedConfiguration(): ConfigProvider + { + $provider = new ConfigProvider(); + self::assertEquals($this->config, $provider->getDependencies()); + + return $provider; + } + + #[Depends('testProvidesExpectedConfiguration')] + public function testInvocationProvidesDependencyConfiguration(ConfigProvider $provider): void + { + self::assertEquals(['dependencies' => $provider->getDependencies()], $provider()); + } +} diff --git a/test/unit/Adapter/ModuleTest.php b/test/unit/Adapter/ModuleTest.php new file mode 100644 index 0000000..772bc06 --- /dev/null +++ b/test/unit/Adapter/ModuleTest.php @@ -0,0 +1,42 @@ +> */ + private array $config = [ + 'aliases' => [ + PlatformInterface::class => Platform\Pgsql::class, + ProfilerInterface::class => Profiler::class, + ], + 'factories' => [ + AdapterInterface::class => AdapterServiceFactory::class, + DriverInterface::class => Driver\Pdo\DriverFactory::class, + Platform\Pgsql::class => InvokableFactory::class, + Profiler::class => InvokableFactory::class, + ], + ]; + + public function testProvidesExpectedConfiguration(): Module + { + $provider = new Module(); + self::assertEquals(['service_manager' => $this->config], $provider->getConfig()); + + return $provider; + } +} From ac20944d7e2edf8ae664aec4360ef2d3a61e308f Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Sun, 28 Sep 2025 02:38:38 -0500 Subject: [PATCH 2/9] This commit starts the work of completing the code migration to this package and aligning the adapter with php-db/phpdb and the current implementation used by the other adapters. Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- .ci/pgsql_fixtures.sh | 6 + .gitattributes | 11 + .github/workflows/continuous-integration.yml | 47 + .../workflows/release-on-milestone-closed.yml | 15 + .gitignore | 4 +- .laminas-ci.json | 12 + .laminas-ci/phpunit.xml | 29 + .laminas-ci/pre-install.sh | 17 + .laminas-ci/pre-run.sh | 22 + README.md | 5 +- compose.yml | 30 +- composer.json | 34 +- composer.lock | 5221 ++++------------- phpstan-baseline.neon | 2 + phpstan.neon.dist | 17 + psalm-baseline.xml | 1063 ---- psalm.xml.dist | 71 - psr-container.php.stub | 23 - renovate.json | 2 +- src/Adapter.php | 17 - src/ConfigProvider.php | 18 +- src/{ => Container}/AdapterServiceFactory.php | 11 +- src/Driver/DatabasePlatformNameTrait.php | 2 +- src/Driver/Pdo/Connection.php | 18 +- src/Driver/Pdo/DriverFactory.php | 4 +- src/Driver/Pdo/Pdo.php | 22 +- src/Driver/Pdo/Result.php | 4 +- src/Driver/Pdo/Statement.php | 4 +- src/Driver/Pgsql/Connection.php | 12 +- src/Driver/Pgsql/Pgsql.php | 16 +- src/Driver/Pgsql/PgsqlConfig.php | 4 +- src/Driver/Pgsql/Result.php | 8 +- src/Driver/Pgsql/Statement.php | 16 +- src/Module.php | 15 - src/Platform/Postgresql.php | 22 +- src/test.php | 20 - .../Factory/AbstractFactoryInterface.stub | 19 + .../Factory/DelegatorFactoryInterface.stub | 27 + .../Factory/FactoryInterface.stub | 21 + .../Factory/InvokableFactory.stub | 22 + .../Initializer/InitializerInterface.stub | 19 + stubs/Psr/Container/ContainerInterface.stub | 22 + .../Driver/Pdo/Postgresql/AdapterTrait.php | 2 +- .../Pdo/Postgresql/TableGatewayTest.php | 8 +- .../Adapter/Platform/PostgresqlTest.php | 8 +- .../Adapter/AdapterServiceFactoryTest.php | 10 +- test/unit/Adapter/AdapterTest.php | 24 +- test/unit/Adapter/ConfigProviderTest.php | 18 +- test/unit/Adapter/ModuleTest.php | 18 +- 49 files changed, 1601 insertions(+), 5461 deletions(-) create mode 100644 .ci/pgsql_fixtures.sh create mode 100644 .gitattributes create mode 100644 .github/workflows/continuous-integration.yml create mode 100644 .github/workflows/release-on-milestone-closed.yml create mode 100644 .laminas-ci.json create mode 100644 .laminas-ci/phpunit.xml create mode 100644 .laminas-ci/pre-install.sh create mode 100644 .laminas-ci/pre-run.sh create mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon.dist delete mode 100644 psalm-baseline.xml delete mode 100644 psalm.xml.dist delete mode 100644 psr-container.php.stub delete mode 100644 src/Adapter.php rename src/{ => Container}/AdapterServiceFactory.php (79%) delete mode 100644 src/Module.php delete mode 100644 src/test.php create mode 100644 stubs/Laminas/ServiceManager/Factory/AbstractFactoryInterface.stub create mode 100644 stubs/Laminas/ServiceManager/Factory/DelegatorFactoryInterface.stub create mode 100644 stubs/Laminas/ServiceManager/Factory/FactoryInterface.stub create mode 100644 stubs/Laminas/ServiceManager/Factory/InvokableFactory.stub create mode 100644 stubs/Laminas/ServiceManager/Initializer/InitializerInterface.stub create mode 100644 stubs/Psr/Container/ContainerInterface.stub diff --git a/.ci/pgsql_fixtures.sh b/.ci/pgsql_fixtures.sh new file mode 100644 index 0000000..2c872a3 --- /dev/null +++ b/.ci/pgsql_fixtures.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +echo "Configure PostgreSQL test database" + +psql -U postgres -c 'create database phpdb_test;' +psql -U postgres -c "alter role postgres password 'postgres'" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..4368bd2 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +/.gitattributes export-ignore +/.github/ export-ignore +/.gitignore export-ignore +/phpcs.xml export-ignore +/renovate.json export-ignore +/.laminas-ci.json export-ignore +/.laminas-ci/ export-ignore +/.ci/ export-ignore +/phpunit.xml.dist export-ignore +/test/ export-ignore +/clover.xml export-ignore \ No newline at end of file diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..7ed76f2 --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,47 @@ +name: "Continuous Integration" + +on: + pull_request: + push: + branches: + tags: + +jobs: + matrix: + name: Generate job matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.matrix.outputs.matrix }} + steps: + - name: Gather CI configuration + id: matrix + uses: laminas/laminas-ci-matrix-action@v1 + + qa: + name: QA Checks + needs: [matrix] + runs-on: ${{ matrix.operatingSystem }} + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.matrix.outputs.matrix) }} + steps: + - name: ${{ matrix.name }} + uses: laminas/laminas-continuous-integration-action@v1 + with: + job: ${{ matrix.job }} + services: + mysql: + image: mysql:5.7 + env: + MYSQL_ROOT_PASSWORD: 'password' + MYSQL_ROOT_HOST: '%' + MYSQL_USER: 'gha' + MYSQL_PASSWORD: 'password' + MYSQL_DATABASE: 'laminasdb_test' + options: >- + --health-cmd="mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 3 + ports: + - 3306 \ No newline at end of file diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml new file mode 100644 index 0000000..a52f436 --- /dev/null +++ b/.github/workflows/release-on-milestone-closed.yml @@ -0,0 +1,15 @@ +name: "Automatic Releases" + +on: + milestone: + types: + - "closed" + +jobs: + release: + uses: laminas/workflow-automatic-releases/.github/workflows/release-on-milestone-closed.yml@1.x + secrets: + GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }} + GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }} + ORGANIZATION_ADMIN_TOKEN: ${{ secrets.ORGANIZATION_ADMIN_TOKEN }} + SIGNING_SECRET_KEY: ${{ secrets.SIGNING_SECRET_KEY }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3df39e0..0088c44 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ /.phpcs-cache +/.phpstan-cache +/phpstan.neon /.phpunit.cache /.phpunit.result.cache /phpunit.xml /vendor/ /xdebug_filter.php -/clover.xml +/clover.xml \ No newline at end of file diff --git a/.laminas-ci.json b/.laminas-ci.json new file mode 100644 index 0000000..10c530b --- /dev/null +++ b/.laminas-ci.json @@ -0,0 +1,12 @@ +{ + "additional_checks": [ + { + "name": "PhpStan", + "job": { + "php": "8.2", + "dependencies": "latest", + "command": "composer require --dev phpstan/phpstan && vendor/bin/phpstan analyse" + } + } + ] +} \ No newline at end of file diff --git a/.laminas-ci/phpunit.xml b/.laminas-ci/phpunit.xml new file mode 100644 index 0000000..af92d7b --- /dev/null +++ b/.laminas-ci/phpunit.xml @@ -0,0 +1,29 @@ + + + + + + + + + ./test/unit + + + ./test/integration + + + + + + + + + + + + diff --git a/.laminas-ci/pre-install.sh b/.laminas-ci/pre-install.sh new file mode 100644 index 0000000..a3c153e --- /dev/null +++ b/.laminas-ci/pre-install.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +WORKING_DIRECTORY=$2 +JOB=$3 +PHP_VERSION=$(echo "${JOB}" | jq -r '.php') + + +if [ ! -z "$GITHUB_BASE_REF" ] && [[ "$GITHUB_BASE_REF" =~ ^[0-9]+\.[0-9] ]]; then + readarray -td. TARGET_BRANCH_VERSION_PARTS <<<"${GITHUB_BASE_REF}."; + unset 'TARGET_BRANCH_VERSION_PARTS[-1]'; + declare -a TARGET_BRANCH_VERSION_PARTS + MAJOR_OF_TARGET_BRANCH=${TARGET_BRANCH_VERSION_PARTS[0]} + MINOR_OF_TARGET_BRANCH=${TARGET_BRANCH_VERSION_PARTS[1]} + + export COMPOSER_ROOT_VERISON="${MAJOR_OF_TARGET_BRANCH}.${MINOR_OF_TARGET_BRANCH}.99" + echo "Exported COMPOSER_ROOT_VERISON as ${COMPOSER_ROOT_VERISON}" +fi diff --git a/.laminas-ci/pre-run.sh b/.laminas-ci/pre-run.sh new file mode 100644 index 0000000..660082a --- /dev/null +++ b/.laminas-ci/pre-run.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -e + +TEST_USER=$1 +WORKSPACE=$2 +JOB=$3 + +COMMAND=$(echo "${JOB}" | jq -r '.command') + +if [[ ! ${COMMAND} =~ phpunit ]]; then + exit 0 +fi + +PHP_VERSION=$(echo "${JOB}" | jq -r '.php') + +# Install CI version of phpunit config +cp .laminas-ci/phpunit.xml phpunit.xml + +# Install lsof (used in integration tests) +apt update -qq +apt install -yqq lsof diff --git a/README.md b/README.md index 5919748..5f93a4e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# axleus-repo-template -Template repo for starting all new repo's +# phpdb-adapter-pgsql + +PostgreSQL Adapter for PHPDb diff --git a/compose.yml b/compose.yml index 0bb7326..704f405 100644 --- a/compose.yml +++ b/compose.yml @@ -8,24 +8,26 @@ services: volumes: - ./:/var/www/html depends_on: - - mysql + - postgresql - mysql: + postgresql: build: context: ./ - dockerfile: docker/databases/mysql/Dockerfile + dockerfile: docker/databases/postgresql/Dockerfile args: - - VERSION=${MYSQL_VERSION:-8.0.41} + - VERSION=${VERSION:-17.4} + - ALPINE_VERSION=${ALPINE_VERSION:-3.21} ports: - - "3306:3306" - environment: - - MYSQL_DATABASE=${MYSQL_DATABASE:-laminasdb_test} - - MYSQL_USER=${MYSQL_USER:-user} - - MYSQL_PASSWORD=${MYSQL_PASSWORD:-password} - - MYSQL_RANDOM_ROOT_PASSWORD=${MYSQL_RANDOM_ROOT_PASSWORD:-yes} + - "5432:5432" volumes: - - ./test/integration/TestFixtures/mysql.sql:/docker-entrypoint-initdb.d/mysql.sql + - ./test/integration/TestFixtures/pgsql.sql:/docker-entrypoint-initdb.d/pgsql.sql + environment: + - POSTGRES_DB=${POSTGRES_DB:-phpdb_test} + - POSTGRES_USER=${POSTGRES_USER:-postgres} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres} healthcheck: - test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] - timeout: 20s - retries: 10 + test: ["CMD-SHELL", "sh -c 'pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-phpdb_test}'"] + interval: 30s + timeout: 60s + retries: 5 + start_period: 80s \ No newline at end of file diff --git a/composer.json b/composer.json index 54ed8c2..483e2b2 100644 --- a/composer.json +++ b/composer.json @@ -26,54 +26,50 @@ }, "extra": { "laminas": { - "component": "Laminas\\Db\\Pgsql", - "config-provider": "Laminas\\Db\\Pgsql\\ConfigProvider" + "config-provider": "PhpDb\\Adapter\\Pgsql\\ConfigProvider" } }, - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/axleus/laminas-db" - } - ], "require": { "php": "~8.2.0 || ~8.3.0 || ~8.4.0", - "laminas/laminas-db": "dev-adapter-migration-mysql-refactor", - "ext-pdo": "*", - "ext-pdo_pgsql": "*" + "php-db/phpdb": "^0.1.0" }, "require-dev": { "laminas/laminas-coding-standard": "^3.0.1", - "phpunit/phpunit": "^11.5.15", - "psalm/plugin-phpunit": "^0.19.2", - "vimeo/psalm": "^6.8.8" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^11.5.15" }, "suggest": { + "ext-pdo": "*", + "ext-pdo_pgsql": "*", "ext-pgsql": "*", "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" }, "autoload": { "psr-4": { - "Laminas\\Db\\Pgsql\\": "src/" + "PhpDb\\Adapter\\Pgsql\\": "src/" } }, "autoload-dev": { "psr-4": { - "LaminasTest\\Db\\Pgsql\\": "test/unit/", - "LaminasIntegrationTest\\Db\\Pgsql\\": "test/integration/" + "PhpDbTest\\Adapter\\Pgsql\\": "test/unit/", + "PhpDbIntegrationTest\\Adapter\\Pgsql\\": "test/integration/" } }, "scripts": { "check": [ "@cs-check", - "@test" + "@static-analysis", + "@test", + "@test-integration" ], "cs-check": "phpcs", "cs-fix": "phpcbf", "test": "phpunit --colors=always --testsuite \"unit test\"", "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", "test-integration": "phpunit --colors=always --testsuite \"integration test\"", - "static-analysis": "psalm --shepherd --stats", + "static-analysis": "vendor/bin/phpstan analyse --memory-limit=256M", + "sa-generate-baseline": "vendor/bin/phpstan analyse --memory-limit=256M --generate-baseline", "upload-coverage": "coveralls -v" } } diff --git a/composer.lock b/composer.lock index 074c38c..26eaed0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ee3918e02f4a5515cf0c24f31cb8786b", + "content-hash": "c8dc357412a66d28ec86e4bfc2d6a17a", "packages": [ { "name": "brick/varexporter", @@ -55,107 +55,6 @@ ], "time": "2024-05-10T17:15:19+00:00" }, - { - "name": "laminas/laminas-db", - "version": "dev-adapter-migration-mysql-refactor", - "source": { - "type": "git", - "url": "https://github.com/axleus/laminas-db.git", - "reference": "a33223ab8deeaa6b17366f7a61fb8d2078a7efa3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/axleus/laminas-db/zipball/a33223ab8deeaa6b17366f7a61fb8d2078a7efa3", - "reference": "a33223ab8deeaa6b17366f7a61fb8d2078a7efa3", - "shasum": "" - }, - "require": { - "laminas/laminas-servicemanager": "^4.0.0", - "laminas/laminas-stdlib": "^3.20.0", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" - }, - "conflict": { - "zendframework/zend-db": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^3.0.1", - "laminas/laminas-eventmanager": "^3.14.0", - "laminas/laminas-servicemanager": "^4.0.0", - "phpunit/phpunit": "^11.5.12", - "psalm/plugin-phpunit": "^0.19.2", - "rector/rector": "^2.0", - "vimeo/psalm": "^6.8.8" - }, - "suggest": { - "laminas/laminas-eventmanager": "Laminas\\EventManager component", - "laminas/laminas-hydrator": "(^5.0.0) Laminas\\Hydrator component for using HydratingResultSets", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Db\\": "src/", - "CustomRule\\PHPUnit\\": "rector/" - } - }, - "autoload-dev": { - "psr-4": { - "LaminasTest\\Db\\": "test/unit/", - "LaminasIntegrationTest\\Db\\": "test/integration/" - } - }, - "scripts": { - "check": [ - "@cs-check", - "@test" - ], - "cs-check": [ - "phpcs" - ], - "cs-fix": [ - "phpcbf" - ], - "test": [ - "phpunit --colors=always --testsuite \"unit test\"" - ], - "test-coverage": [ - "phpunit --colors=always --coverage-clover clover.xml" - ], - "test-integration": [ - "phpunit --colors=always --testsuite \"integration test\"" - ], - "static-analysis": [ - "psalm --shepherd --stats" - ], - "upload-coverage": [ - "coveralls -v" - ] - }, - "license": [ - "BSD-3-Clause" - ], - "description": "Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations", - "homepage": "https://laminas.dev", - "keywords": [ - "db", - "laminas" - ], - "support": { - "docs": "https://docs.laminas.dev/laminas-db/", - "issues": "https://github.com/laminas/laminas-db/issues", - "source": "https://github.com/laminas/laminas-db", - "rss": "https://github.com/laminas/laminas-db/releases.atom", - "chat": "https://laminas.dev/chat", - "forum": "https://discourse.laminas.dev" - }, - "funding": [ - { - "type": "github", - "url": "https://github.com/AXLEUS" - } - ], - "time": "2025-05-23T07:07:25+00:00" - }, { "name": "laminas/laminas-servicemanager", "version": "4.4.0", @@ -302,16 +201,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.4.0", + "version": "v5.6.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", + "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "shasum": "" }, "require": { @@ -330,7 +229,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "5.x-dev" } }, "autoload": { @@ -354,9 +253,75 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" }, - "time": "2024-12-30T11:07:19+00:00" + "time": "2025-08-13T20:13:15+00:00" + }, + { + "name": "php-db/phpdb", + "version": "0.1.1", + "source": { + "type": "git", + "url": "https://github.com/php-db/phpdb.git", + "reference": "f671eabd951cd5da927ea814c8d0f83bb16247e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-db/phpdb/zipball/f671eabd951cd5da927ea814c8d0f83bb16247e0", + "reference": "f671eabd951cd5da927ea814c8d0f83bb16247e0", + "shasum": "" + }, + "require": { + "laminas/laminas-servicemanager": "^4.0.0", + "laminas/laminas-stdlib": "^3.20.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "conflict": { + "laminas/laminas-db": "*", + "zendframework/zend-db": "*" + }, + "require-dev": { + "laminas/laminas-coding-standard": "^3.0.1", + "laminas/laminas-eventmanager": "^3.14.0", + "phpunit/phpunit": "^11.5.12", + "psalm/plugin-phpunit": "^0.19.2", + "rector/rector": "^2.0", + "vimeo/psalm": "^6.8.8" + }, + "suggest": { + "laminas/laminas-eventmanager": "Laminas\\EventManager component", + "laminas/laminas-hydrator": "(^5.0.0) Laminas\\Hydrator component for using HydratingResultSets" + }, + "type": "library", + "extra": { + "laminas": { + "config-provider": "PhpDb\\Container\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "PhpDb\\": "src/", + "CustomRule\\PHPUnit\\": "rector/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations", + "homepage": "https://php-db.dev", + "keywords": [ + "db", + "laminas", + "mezzio", + "php-db" + ], + "support": { + "docs": "https://docs.php-db.dev/", + "issues": "https://github.com/php-db/phpdb/issues", + "source": "https://github.com/php-db/phpdb" + }, + "time": "2025-09-15T22:14:40+00:00" }, { "name": "psr/container", @@ -414,37 +379,39 @@ ], "packages-dev": [ { - "name": "amphp/amp", - "version": "v3.1.0", + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v1.1.2", "source": { "type": "git", - "url": "https://github.com/amphp/amp.git", - "reference": "7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9" + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9", - "reference": "7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", + "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", "shasum": "" }, "require": { - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" + "composer-plugin-api": "^2.2", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "phpunit/phpunit": "^9", - "psalm/phar": "5.23.1" + "composer/composer": "^2.2", + "ext-json": "*", + "ext-zip": "*", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, - "type": "library", "autoload": { - "files": [ - "src/functions.php", - "src/Future/functions.php", - "src/Internal/functions.php" - ], "psr-4": { - "Amp\\": "src" + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -453,3530 +420,998 @@ ], "authors": [ { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Franck Nijhof", + "email": "opensource@frenck.dev", + "homepage": "https://frenck.dev", + "role": "Open source developer" }, { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" } ], - "description": "A non-blocking concurrency framework for PHP applications.", - "homepage": "https://amphp.org/amp", + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", "keywords": [ - "async", - "asynchronous", - "awaitable", - "concurrency", - "event", - "event-loop", - "future", - "non-blocking", - "promise" + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" ], "support": { - "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v3.1.0" + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "security": "https://github.com/PHPCSStandards/composer-installer/security/policy", + "source": "https://github.com/PHPCSStandards/composer-installer" }, "funding": [ { - "url": "https://github.com/amphp", + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2025-01-26T16:07:39+00:00" + "time": "2025-07-17T20:45:56+00:00" }, { - "name": "amphp/byte-stream", - "version": "v2.1.2", + "name": "laminas/laminas-coding-standard", + "version": "3.1.0", "source": { "type": "git", - "url": "https://github.com/amphp/byte-stream.git", - "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46" + "url": "https://github.com/laminas/laminas-coding-standard.git", + "reference": "d4412caba9ed16c93cdcf301759f5ee71f9d9aea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/55a6bd071aec26fa2a3e002618c20c35e3df1b46", - "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46", + "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/d4412caba9ed16c93cdcf301759f5ee71f9d9aea", + "reference": "d4412caba9ed16c93cdcf301759f5ee71f9d9aea", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/parser": "^1.1", - "amphp/pipeline": "^1", - "amphp/serialization": "^1", - "amphp/sync": "^2", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2.3" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "5.22.1" + "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.0", + "php": "^7.4 || ^8.0", + "slevomat/coding-standard": "^8.15.0", + "squizlabs/php_codesniffer": "^3.10", + "webimpress/coding-standard": "^1.3" }, - "type": "library", + "type": "phpcodesniffer-standard", "autoload": { - "files": [ - "src/functions.php", - "src/Internal/functions.php" - ], "psr-4": { - "Amp\\ByteStream\\": "src" + "LaminasCodingStandard\\": "src/LaminasCodingStandard/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } + "BSD-3-Clause" ], - "description": "A stream abstraction to make working with non-blocking I/O simple.", - "homepage": "https://amphp.org/byte-stream", + "description": "Laminas Coding Standard", + "homepage": "https://laminas.dev", "keywords": [ - "amp", - "amphp", - "async", - "io", - "non-blocking", - "stream" + "Coding Standard", + "laminas" ], "support": { - "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v2.1.2" + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-coding-standard/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-coding-standard/issues", + "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", + "source": "https://github.com/laminas/laminas-coding-standard" }, "funding": [ { - "url": "https://github.com/amphp", - "type": "github" + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" } ], - "time": "2025-03-16T17:10:27+00:00" + "time": "2025-05-13T08:37:04+00:00" }, { - "name": "amphp/cache", - "version": "v2.0.1", + "name": "myclabs/deep-copy", + "version": "1.13.4", "source": { "type": "git", - "url": "https://github.com/amphp/cache.git", - "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/cache/zipball/46912e387e6aa94933b61ea1ead9cf7540b7797c", - "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/serialization": "^1", - "amphp/sync": "^2", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.4" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], "psr-4": { - "Amp\\Cache\\": "src" + "DeepCopy\\": "src/DeepCopy/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - } + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" ], - "description": "A fiber-aware cache API based on Amp and Revolt.", - "homepage": "https://amphp.org/cache", "support": { - "issues": "https://github.com/amphp/cache/issues", - "source": "https://github.com/amphp/cache/tree/v2.0.1" + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" }, "funding": [ { - "url": "https://github.com/amphp", - "type": "github" + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" } ], - "time": "2024-04-19T03:38:06+00:00" + "time": "2025-08-01T08:46:24+00:00" }, { - "name": "amphp/dns", - "version": "v2.4.0", + "name": "phar-io/manifest", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/amphp/dns.git", - "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71" + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/dns/zipball/78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", - "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/byte-stream": "^2", - "amphp/cache": "^2", - "amphp/parser": "^1", - "amphp/process": "^2", - "daverandom/libdns": "^2.0.2", - "ext-filter": "*", - "ext-json": "*", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "5.20" + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Amp\\Dns\\": "src" + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Chris Wright", - "email": "addr@daverandom.com" - }, - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - }, - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" }, { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" }, { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "Async DNS resolution for Amp.", - "homepage": "https://github.com/amphp/dns", - "keywords": [ - "amp", - "amphp", - "async", - "client", - "dns", - "resolve" - ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { - "issues": "https://github.com/amphp/dns/issues", - "source": "https://github.com/amphp/dns/tree/v2.4.0" + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, "funding": [ { - "url": "https://github.com/amphp", + "url": "https://github.com/theseer", "type": "github" } ], - "time": "2025-01-19T15:43:40+00:00" + "time": "2024-03-03T12:33:53+00:00" }, { - "name": "amphp/parallel", - "version": "v2.3.1", + "name": "phar-io/version", + "version": "3.2.1", "source": { "type": "git", - "url": "https://github.com/amphp/parallel.git", - "reference": "5113111de02796a782f5d90767455e7391cca190" + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/parallel/zipball/5113111de02796a782f5d90767455e7391cca190", - "reference": "5113111de02796a782f5d90767455e7391cca190", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/byte-stream": "^2", - "amphp/cache": "^2", - "amphp/parser": "^1", - "amphp/pipeline": "^1", - "amphp/process": "^2", - "amphp/serialization": "^1", - "amphp/socket": "^2", - "amphp/sync": "^2", - "php": ">=8.1", - "revolt/event-loop": "^1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.18" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { - "files": [ - "src/Context/functions.php", - "src/Context/Internal/functions.php", - "src/Ipc/functions.php", - "src/Worker/functions.php" - ], - "psr-4": { - "Amp\\Parallel\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" }, { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" }, { - "name": "Stephen Coakley", - "email": "me@stephencoakley.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "Parallel processing component for Amp.", - "homepage": "https://github.com/amphp/parallel", - "keywords": [ - "async", - "asynchronous", - "concurrent", - "multi-processing", - "multi-threading" - ], + "description": "Library for handling version information and constraints", "support": { - "issues": "https://github.com/amphp/parallel/issues", - "source": "https://github.com/amphp/parallel/tree/v2.3.1" + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-12-21T01:56:09+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { - "name": "amphp/parser", - "version": "v1.1.1", + "name": "phpstan/phpdoc-parser", + "version": "2.3.0", "source": { "type": "git", - "url": "https://github.com/amphp/parser.git", - "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7" + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/parser/zipball/3cf1f8b32a0171d4b1bed93d25617637a77cded7", - "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", "shasum": "" }, "require": { - "php": ">=7.4" + "php": "^7.4 || ^8.0" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.4" + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" }, "type": "library", "autoload": { "psr-4": { - "Amp\\Parser\\": "src" + "PHPStan\\PhpDocParser\\": [ + "src/" + ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A generator parser to make streaming parsers simple.", - "homepage": "https://github.com/amphp/parser", - "keywords": [ - "async", - "non-blocking", - "parser", - "stream" - ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { - "issues": "https://github.com/amphp/parser/issues", - "source": "https://github.com/amphp/parser/tree/v1.1.1" + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0" }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-03-21T19:16:53+00:00" + "time": "2025-08-30T15:50:23+00:00" }, { - "name": "amphp/pipeline", - "version": "v1.2.3", + "name": "phpstan/phpstan", + "version": "2.1.29", "source": { "type": "git", - "url": "https://github.com/amphp/pipeline.git", - "reference": "7b52598c2e9105ebcddf247fc523161581930367" + "url": "https://github.com/phpstan/phpstan-phar-composer-source.git", + "reference": "git" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/pipeline/zipball/7b52598c2e9105ebcddf247fc523161581930367", - "reference": "7b52598c2e9105ebcddf247fc523161581930367", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d618573eed4a1b6b75e37b2e0b65ac65c885d88e", + "reference": "d618573eed4a1b6b75e37b2e0b65ac65c885d88e", "shasum": "" }, "require": { - "amphp/amp": "^3", - "php": ">=8.1", - "revolt/event-loop": "^1" + "php": "^7.4|^8.0" }, - "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.18" + "conflict": { + "phpstan/phpstan-shim": "*" }, + "bin": [ + "phpstan", + "phpstan.phar" + ], "type": "library", "autoload": { - "psr-4": { - "Amp\\Pipeline\\": "src" - } + "files": [ + "bootstrap.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "Asynchronous iterators and operators.", - "homepage": "https://amphp.org/pipeline", + "description": "PHPStan - PHP Static Analysis Tool", "keywords": [ - "amp", - "amphp", - "async", - "io", - "iterator", - "non-blocking" + "dev", + "static analysis" ], "support": { - "issues": "https://github.com/amphp/pipeline/issues", - "source": "https://github.com/amphp/pipeline/tree/v1.2.3" + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" }, "funding": [ { - "url": "https://github.com/amphp", + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", "type": "github" } ], - "time": "2025-03-16T16:33:53+00:00" + "time": "2025-09-25T06:58:18+00:00" }, { - "name": "amphp/process", - "version": "v2.0.3", + "name": "phpstan/phpstan-phpunit", + "version": "2.0.7", "source": { "type": "git", - "url": "https://github.com/amphp/process.git", - "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d" + "url": "https://github.com/phpstan/phpstan-phpunit.git", + "reference": "9a9b161baee88a5f5c58d816943cff354ff233dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/process/zipball/52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", - "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/9a9b161baee88a5f5c58d816943cff354ff233dc", + "reference": "9a9b161baee88a5f5c58d816943cff354ff233dc", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/byte-stream": "^2", - "amphp/sync": "^2", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.1.18" + }, + "conflict": { + "phpunit/phpunit": "<7.0" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.4" + "nikic/php-parser": "^5", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } }, - "type": "library", "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { - "Amp\\Process\\": "src" + "PHPStan\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A fiber-aware process manager based on Amp and Revolt.", - "homepage": "https://amphp.org/process", + "description": "PHPUnit extensions and rules for PHPStan", "support": { - "issues": "https://github.com/amphp/process/issues", - "source": "https://github.com/amphp/process/tree/v2.0.3" + "issues": "https://github.com/phpstan/phpstan-phpunit/issues", + "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.7" }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-04-19T03:13:44+00:00" + "time": "2025-07-13T11:31:46+00:00" }, { - "name": "amphp/serialization", - "version": "v1.0.0", + "name": "phpunit/php-code-coverage", + "version": "11.0.11", "source": { "type": "git", - "url": "https://github.com/amphp/serialization.git", - "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1" + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/serialization/zipball/693e77b2fb0b266c3c7d622317f881de44ae94a1", - "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4", + "reference": "4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.4.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "phpunit/phpunit": "^9 || ^8 || ^7" + "phpunit/phpunit": "^11.5.2" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Amp\\Serialization\\": "src" + "extra": { + "branch-alias": { + "dev-main": "11.0.x-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Serialization tools for IPC and data storage in PHP.", - "homepage": "https://github.com/amphp/serialization", + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ - "async", - "asynchronous", - "serialization", - "serialize" + "coverage", + "testing", + "xunit" ], "support": { - "issues": "https://github.com/amphp/serialization/issues", - "source": "https://github.com/amphp/serialization/tree/master" + "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.11" }, - "time": "2020-03-25T21:39:07+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" + } + ], + "time": "2025-08-27T14:37:49+00:00" }, { - "name": "amphp/socket", - "version": "v2.3.1", + "name": "phpunit/php-file-iterator", + "version": "5.1.0", "source": { "type": "git", - "url": "https://github.com/amphp/socket.git", - "reference": "58e0422221825b79681b72c50c47a930be7bf1e1" + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/socket/zipball/58e0422221825b79681b72c50c47a930be7bf1e1", - "reference": "58e0422221825b79681b72c50c47a930be7bf1e1", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/byte-stream": "^2", - "amphp/dns": "^2", - "ext-openssl": "*", - "kelunik/certificate": "^1.1", - "league/uri": "^6.5 | ^7", - "league/uri-interfaces": "^2.3 | ^7", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" + "php": ">=8.2" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "amphp/process": "^2", - "phpunit/phpunit": "^9", - "psalm/phar": "5.20" + "phpunit/phpunit": "^11.0" }, "type": "library", - "autoload": { - "files": [ - "src/functions.php", - "src/Internal/functions.php", - "src/SocketAddress/functions.php" - ], - "psr-4": { - "Amp\\Socket\\": "src" + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Daniel Lowrey", - "email": "rdlowrey@gmail.com" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Non-blocking socket connection / server implementations based on Amp and Revolt.", - "homepage": "https://github.com/amphp/socket", + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ - "amp", - "async", - "encryption", - "non-blocking", - "sockets", - "tcp", - "tls" + "filesystem", + "iterator" ], "support": { - "issues": "https://github.com/amphp/socket/issues", - "source": "https://github.com/amphp/socket/tree/v2.3.1" + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" }, "funding": [ { - "url": "https://github.com/amphp", + "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2024-04-21T14:33:03+00:00" + "time": "2024-08-27T05:02:59+00:00" }, { - "name": "amphp/sync", - "version": "v2.3.0", + "name": "phpunit/php-invoker", + "version": "5.0.1", "source": { "type": "git", - "url": "https://github.com/amphp/sync.git", - "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/sync/zipball/217097b785130d77cfcc58ff583cf26cd1770bf1", - "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/pipeline": "^1", - "amphp/serialization": "^1", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" + "php": ">=8.2" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "5.23" + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" }, "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Amp\\Sync\\": "src" + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - }, - { - "name": "Stephen Coakley", - "email": "me@stephencoakley.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Non-blocking synchronization primitives for PHP based on Amp and Revolt.", - "homepage": "https://github.com/amphp/sync", + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", "keywords": [ - "async", - "asynchronous", - "mutex", - "semaphore", - "synchronization" + "process" ], "support": { - "issues": "https://github.com/amphp/sync/issues", - "source": "https://github.com/amphp/sync/tree/v2.3.0" + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" }, "funding": [ { - "url": "https://github.com/amphp", + "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2024-08-03T19:31:26+00:00" + "time": "2024-07-03T05:07:44+00:00" }, { - "name": "composer/pcre", - "version": "3.3.2", + "name": "phpunit/php-text-template", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/composer/pcre.git", - "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", - "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<1.11.10" + "php": ">=8.2" }, "require-dev": { - "phpstan/phpstan": "^1.12 || ^2", - "phpstan/phpstan-strict-rules": "^1 || ^2", - "phpunit/phpunit": "^8 || ^9" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { - "phpstan": { - "includes": [ - "extension.neon" - ] - }, "branch-alias": { - "dev-main": "3.x-dev" + "dev-main": "4.0-dev" } }, "autoload": { - "psr-4": { - "Composer\\Pcre\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "PCRE", - "preg", - "regex", - "regular expression" + "template" ], "support": { - "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.3.2" + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" }, "funding": [ { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2024-11-12T16:29:46+00:00" + "time": "2024-07-03T05:08:43+00:00" }, { - "name": "composer/semver", - "version": "3.4.3", + "name": "phpunit/php-timer", + "version": "7.0.1", "source": { "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": ">=8.2" }, "require-dev": { - "phpstan/phpstan": "^1.11", - "symfony/phpunit-bridge": "^3 || ^7" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.x-dev" + "dev-main": "7.0-dev" } }, "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ - "semantic", - "semver", - "validation", - "versioning" + "timer" ], "support": { - "irc": "ircs://irc.libera.chat:6697/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.3" + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" }, "funding": [ { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2024-09-19T14:15:21+00:00" + "time": "2024-07-03T05:09:35+00:00" }, { - "name": "composer/xdebug-handler", - "version": "3.0.5", + "name": "phpunit/phpunit", + "version": "11.5.41", "source": { "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "b42782bcb947d2c197aea42ce9714ee2d974b283" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", - "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b42782bcb947d2c197aea42ce9714ee2d974b283", + "reference": "b42782bcb947d2c197aea42ce9714ee2d974b283", "shasum": "" }, "require": { - "composer/pcre": "^1 || ^2 || ^3", - "php": "^7.2.5 || ^8.0", - "psr/log": "^1 || ^2 || ^3" + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.11", + "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.3", + "sebastian/comparator": "^6.3.2", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.1", + "sebastian/exporter": "^6.3.2", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.3", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" }, - "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" }, + "bin": [ + "phpunit" + ], "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" + "extra": { + "branch-alias": { + "dev-main": "11.5-dev" } }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Restarts a process without Xdebug.", + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", "keywords": [ - "Xdebug", - "performance" + "phpunit", + "testing", + "xunit" ], "support": { - "irc": "ircs://irc.libera.chat:6697/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.41" }, "funding": [ { - "url": "https://packagist.com", + "url": "https://phpunit.de/sponsors.html", "type": "custom" }, { - "url": "https://github.com/composer", + "url": "https://github.com/sebastianbergmann", "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", "type": "tidelift" } ], - "time": "2024-05-06T16:37:16+00:00" + "time": "2025-09-24T06:32:10+00:00" }, { - "name": "danog/advanced-json-rpc", - "version": "v3.2.2", + "name": "sebastian/cli-parser", + "version": "3.0.2", "source": { "type": "git", - "url": "https://github.com/danog/php-advanced-json-rpc.git", - "reference": "aadb1c4068a88c3d0530cfe324b067920661efcb" + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/danog/php-advanced-json-rpc/zipball/aadb1c4068a88c3d0530cfe324b067920661efcb", - "reference": "aadb1c4068a88c3d0530cfe324b067920661efcb", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", "shasum": "" }, "require": { - "netresearch/jsonmapper": "^5", - "php": ">=8.1", - "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" - }, - "replace": { - "felixfbecker/php-advanced-json-rpc": "^3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9" + "phpunit/phpunit": "^11.0" }, "type": "library", - "autoload": { - "psr-4": { - "AdvancedJsonRpc\\": "lib/" + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "ISC" + "BSD-3-Clause" ], "authors": [ { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - }, - { - "name": "Daniil Gentili", - "email": "daniil@daniil.it" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "A more advanced JSONRPC implementation", + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { - "issues": "https://github.com/danog/php-advanced-json-rpc/issues", - "source": "https://github.com/danog/php-advanced-json-rpc/tree/v3.2.2" + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" }, - "time": "2025-02-14T10:55:15+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" }, { - "name": "daverandom/libdns", - "version": "v2.1.0", + "name": "sebastian/code-unit", + "version": "3.0.3", "source": { "type": "git", - "url": "https://github.com/DaveRandom/LibDNS.git", - "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a" + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DaveRandom/LibDNS/zipball/b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", - "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", "shasum": "" }, "require": { - "ext-ctype": "*", - "php": ">=7.1" + "php": ">=8.2" }, - "suggest": { - "ext-intl": "Required for IDN support" + "require-dev": { + "phpunit/phpunit": "^11.5" }, "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "LibDNS\\": "src/" + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], - "description": "DNS protocol implementation written in pure PHP", - "keywords": [ - "dns" + "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/DaveRandom/LibDNS/issues", - "source": "https://github.com/DaveRandom/LibDNS/tree/v2.1.0" - }, - "time": "2024-04-12T12:12:48+00:00" - }, - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCSStandards/composer-installer.git", - "reference": "4be43904336affa5c2f70744a348312336afd0da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", - "reference": "4be43904336affa5c2f70744a348312336afd0da", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.4", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "ext-json": "*", - "ext-zip": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0", - "yoast/phpunit-polyfills": "^1.0" - }, - "type": "composer-plugin", - "extra": { - "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/PHPCSStandards/composer-installer/issues", - "source": "https://github.com/PHPCSStandards/composer-installer" - }, - "time": "2023-01-05T11:28:13+00:00" - }, - { - "name": "dnoegel/php-xdg-base-dir", - "version": "v0.1.1", - "source": { - "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "XdgBaseDir\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "implementation of xdg base directory specification for php", - "support": { - "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", - "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" - }, - "time": "2019-12-04T15:06:13+00:00" - }, - { - "name": "doctrine/deprecations", - "version": "1.1.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "phpunit/phpunit": "<=7.5 || >=13" - }, - "require-dev": { - "doctrine/coding-standard": "^9 || ^12 || ^13", - "phpstan/phpstan": "1.4.10 || 2.1.11", - "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", - "psr/log": "^1 || ^2 || ^3" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", - "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.5" - }, - "time": "2025-04-07T20:06:18+00:00" - }, - { - "name": "felixfbecker/language-server-protocol", - "version": "v1.5.3", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-language-server-protocol.git", - "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/a9e113dbc7d849e35b8776da39edaf4313b7b6c9", - "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpstan/phpstan": "*", - "squizlabs/php_codesniffer": "^3.1", - "vimeo/psalm": "^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "LanguageServerProtocol\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "PHP classes for the Language Server Protocol", - "keywords": [ - "language", - "microsoft", - "php", - "server" - ], - "support": { - "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", - "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.3" - }, - "time": "2024-04-30T00:40:11+00:00" - }, - { - "name": "fidry/cpu-core-counter", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "8520451a140d3f46ac33042715115e290cf5785f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", - "reference": "8520451a140d3f46ac33042715115e290cf5785f", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "fidry/makefile": "^0.2.0", - "fidry/php-cs-fixer-config": "^1.1.2", - "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^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", - "autoload": { - "psr-4": { - "Fidry\\CpuCoreCounter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Théo FIDRY", - "email": "theo.fidry@gmail.com" - } - ], - "description": "Tiny utility to get the number of CPU cores.", - "keywords": [ - "CPU", - "core" - ], - "support": { - "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" - }, - "funding": [ - { - "url": "https://github.com/theofidry", - "type": "github" - } - ], - "time": "2024-08-06T10:04:20+00:00" - }, - { - "name": "kelunik/certificate", - "version": "v1.1.3", - "source": { - "type": "git", - "url": "https://github.com/kelunik/certificate.git", - "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/kelunik/certificate/zipball/7e00d498c264d5eb4f78c69f41c8bd6719c0199e", - "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e", - "shasum": "" - }, - "require": { - "ext-openssl": "*", - "php": ">=7.0" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "phpunit/phpunit": "^6 | 7 | ^8 | ^9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Kelunik\\Certificate\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "Access certificate details and transform between different formats.", - "keywords": [ - "DER", - "certificate", - "certificates", - "openssl", - "pem", - "x509" - ], - "support": { - "issues": "https://github.com/kelunik/certificate/issues", - "source": "https://github.com/kelunik/certificate/tree/v1.1.3" - }, - "time": "2023-02-03T21:26:53+00:00" - }, - { - "name": "laminas/laminas-coding-standard", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-coding-standard.git", - "reference": "d4412caba9ed16c93cdcf301759f5ee71f9d9aea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/d4412caba9ed16c93cdcf301759f5ee71f9d9aea", - "reference": "d4412caba9ed16c93cdcf301759f5ee71f9d9aea", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.0", - "php": "^7.4 || ^8.0", - "slevomat/coding-standard": "^8.15.0", - "squizlabs/php_codesniffer": "^3.10", - "webimpress/coding-standard": "^1.3" - }, - "type": "phpcodesniffer-standard", - "autoload": { - "psr-4": { - "LaminasCodingStandard\\": "src/LaminasCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Laminas Coding Standard", - "homepage": "https://laminas.dev", - "keywords": [ - "Coding Standard", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-coding-standard/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-coding-standard/issues", - "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", - "source": "https://github.com/laminas/laminas-coding-standard" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2025-05-13T08:37:04+00:00" - }, - { - "name": "league/uri", - "version": "7.5.1", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/uri.git", - "reference": "81fb5145d2644324614cc532b28efd0215bda430" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", - "reference": "81fb5145d2644324614cc532b28efd0215bda430", - "shasum": "" - }, - "require": { - "league/uri-interfaces": "^7.5", - "php": "^8.1" - }, - "conflict": { - "league/uri-schemes": "^1.0" - }, - "suggest": { - "ext-bcmath": "to improve IPV4 host parsing", - "ext-fileinfo": "to create Data URI from file contennts", - "ext-gmp": "to improve IPV4 host parsing", - "ext-intl": "to handle IDN host with the best performance", - "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", - "league/uri-components": "Needed to easily manipulate URI objects components", - "php-64bit": "to improve IPV4 host parsing", - "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Uri\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ignace Nyamagana Butera", - "email": "nyamsprod@gmail.com", - "homepage": "https://nyamsprod.com" - } - ], - "description": "URI manipulation library", - "homepage": "https://uri.thephpleague.com", - "keywords": [ - "data-uri", - "file-uri", - "ftp", - "hostname", - "http", - "https", - "middleware", - "parse_str", - "parse_url", - "psr-7", - "query-string", - "querystring", - "rfc3986", - "rfc3987", - "rfc6570", - "uri", - "uri-template", - "url", - "ws" - ], - "support": { - "docs": "https://uri.thephpleague.com", - "forum": "https://thephpleague.slack.com", - "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.5.1" - }, - "funding": [ - { - "url": "https://github.com/sponsors/nyamsprod", - "type": "github" - } - ], - "time": "2024-12-08T08:40:02+00:00" - }, - { - "name": "league/uri-interfaces", - "version": "7.5.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^8.1", - "psr/http-factory": "^1", - "psr/http-message": "^1.1 || ^2.0" - }, - "suggest": { - "ext-bcmath": "to improve IPV4 host parsing", - "ext-gmp": "to improve IPV4 host parsing", - "ext-intl": "to handle IDN host with the best performance", - "php-64bit": "to improve IPV4 host parsing", - "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Uri\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ignace Nyamagana Butera", - "email": "nyamsprod@gmail.com", - "homepage": "https://nyamsprod.com" - } - ], - "description": "Common interfaces and classes for URI representation and interaction", - "homepage": "https://uri.thephpleague.com", - "keywords": [ - "data-uri", - "file-uri", - "ftp", - "hostname", - "http", - "https", - "parse_str", - "parse_url", - "psr-7", - "query-string", - "querystring", - "rfc3986", - "rfc3987", - "rfc6570", - "uri", - "url", - "ws" - ], - "support": { - "docs": "https://uri.thephpleague.com", - "forum": "https://thephpleague.slack.com", - "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" - }, - "funding": [ - { - "url": "https://github.com/sponsors/nyamsprod", - "type": "github" - } - ], - "time": "2024-12-08T08:18:47+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.13.1", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c", - "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3 <3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpspec/prophecy": "^1.10", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2025-04-29T12:36:36+00:00" - }, - { - "name": "netresearch/jsonmapper", - "version": "v5.0.0", - "source": { - "type": "git", - "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c", - "reference": "8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0", - "squizlabs/php_codesniffer": "~3.5" - }, - "type": "library", - "autoload": { - "psr-0": { - "JsonMapper": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "OSL-3.0" - ], - "authors": [ - { - "name": "Christian Weiske", - "email": "cweiske@cweiske.de", - "homepage": "http://github.com/cweiske/jsonmapper/", - "role": "Developer" - } - ], - "description": "Map nested JSON structures onto PHP classes", - "support": { - "email": "cweiske@cweiske.de", - "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/v5.0.0" - }, - "time": "2024-09-08T10:20:00+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "54750ef60c58e43759730615a392c31c80e23176" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", - "reference": "54750ef60c58e43759730615a392c31c80e23176", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2024-03-03T12:33:53+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.6.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "92dde6a5919e34835c506ac8c523ef095a95ed62" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/92dde6a5919e34835c506ac8c523ef095a95ed62", - "reference": "92dde6a5919e34835c506ac8c523ef095a95ed62", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.1", - "ext-filter": "*", - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7|^2.0", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.5 || ~1.6.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-webmozart-assert": "^1.2", - "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.2" - }, - "time": "2025-04-13T19:20:35+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", - "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", - "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.18|^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" - }, - "time": "2024-11-09T15:12:26+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/9b30d6fd026b2c132b3985ce6b23bec09ab3aa68", - "reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "doctrine/annotations": "^2.0", - "nikic/php-parser": "^5.3.0", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^2.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^9.6", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/2.1.0" - }, - "time": "2025-02-19T13:28:12+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "11.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/14d63fbcca18457e49c6f8bebaa91a87e8e188d7", - "reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^5.4.0", - "php": ">=8.2", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-text-template": "^4.0.1", - "sebastian/code-unit-reverse-lookup": "^4.0.1", - "sebastian/complexity": "^4.0.1", - "sebastian/environment": "^7.2.0", - "sebastian/lines-of-code": "^3.0.1", - "sebastian/version": "^5.0.2", - "theseer/tokenizer": "^1.2.3" - }, - "require-dev": { - "phpunit/phpunit": "^11.5.2" - }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "11.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.9" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-25T13:26:39+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "5.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-08-27T05:02:59+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "5.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^11.0" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:07:44+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:08:43+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "7.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:09:35+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "11.5.21", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d565e2cdc21a7db9dc6c399c1fc2083b8010f289" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d565e2cdc21a7db9dc6c399c1fc2083b8010f289", - "reference": "d565e2cdc21a7db9dc6c399c1fc2083b8010f289", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.1", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", - "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.9", - "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.3", - "sebastian/comparator": "^6.3.1", - "sebastian/diff": "^6.0.2", - "sebastian/environment": "^7.2.1", - "sebastian/exporter": "^6.3.0", - "sebastian/global-state": "^7.0.2", - "sebastian/object-enumerator": "^6.0.1", - "sebastian/type": "^5.1.2", - "sebastian/version": "^5.0.2", - "staabm/side-effects-detector": "^1.0.5" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "11.5-dev" - } - }, - "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.21" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" - } - ], - "time": "2025-05-21T12:35:00+00:00" - }, - { - "name": "psalm/plugin-phpunit", - "version": "0.19.5", - "source": { - "type": "git", - "url": "https://github.com/psalm/psalm-plugin-phpunit.git", - "reference": "143f9d5e049fffcdbc0da3fbb99f6149f9d3e2dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/143f9d5e049fffcdbc0da3fbb99f6149f9d3e2dc", - "reference": "143f9d5e049fffcdbc0da3fbb99f6149f9d3e2dc", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "php": ">=8.1", - "vimeo/psalm": "dev-master || ^6.10.0" - }, - "conflict": { - "phpspec/prophecy": "<1.20.0", - "phpspec/prophecy-phpunit": "<2.3.0", - "phpunit/phpunit": "<8.5.1" - }, - "require-dev": { - "php": "^7.3 || ^8.0", - "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", - "squizlabs/php_codesniffer": "^3.3.1", - "weirdan/prophecy-shim": "^1.0 || ^2.0" - }, - "type": "psalm-plugin", - "extra": { - "psalm": { - "pluginClass": "Psalm\\PhpUnitPlugin\\Plugin" - } - }, - "autoload": { - "psr-4": { - "Psalm\\PhpUnitPlugin\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matt Brown", - "email": "github@muglug.com" - } - ], - "description": "Psalm plugin for PHPUnit", - "support": { - "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues", - "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.19.5" - }, - "time": "2025-03-31T18:49:55+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", - "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "psr/http-message": "^1.0 || ^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-factory" - }, - "time": "2024-04-15T12:06:14+00:00" - }, - { - "name": "psr/http-message", - "version": "2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/2.0" - }, - "time": "2023-04-04T09:54:51+00:00" - }, - { - "name": "psr/log", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.2" - }, - "time": "2024-09-11T13:17:53+00:00" - }, - { - "name": "revolt/event-loop", - "version": "v1.0.7", - "source": { - "type": "git", - "url": "https://github.com/revoltphp/event-loop.git", - "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/09bf1bf7f7f574453efe43044b06fafe12216eb3", - "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.15" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Revolt\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "ceesjank@gmail.com" - }, - { - "name": "Christian Lück", - "email": "christian@clue.engineering" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "Rock-solid event loop for concurrent PHP applications.", - "keywords": [ - "async", - "asynchronous", - "concurrency", - "event", - "event-loop", - "non-blocking", - "scheduler" - ], - "support": { - "issues": "https://github.com/revoltphp/event-loop/issues", - "source": "https://github.com/revoltphp/event-loop/tree/v1.0.7" - }, - "time": "2025-01-25T19:27:39+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.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", - "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", - "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.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-03-19T07:56:08+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.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/24b8fbc2c8e201bb1308e7b05148d6ab393b6959", - "reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959", - "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.3-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.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-03-07T06:57:01+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.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", - "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "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.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", - "type": "tidelift" - } - ], - "time": "2025-05-21T11:55:47+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" - ], - "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" + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" }, "funding": [ { @@ -3984,20 +1419,20 @@ "type": "github" } ], - "time": "2024-07-03T05:00:13+00:00" + "time": "2025-03-19T07:56:08+00:00" }, { - "name": "sebastian/object-reflector", + "name": "sebastian/code-unit-reverse-lookup", "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", "shasum": "" }, "require": { @@ -4027,12 +1462,12 @@ "email": "sebastian@phpunit.de" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "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/object-reflector/issues", - "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + "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": [ { @@ -4040,32 +1475,39 @@ "type": "github" } ], - "time": "2024-07-03T05:01:32+00:00" + "time": "2024-07-03T04:45:54+00:00" }, { - "name": "sebastian/recursion-context", - "version": "6.0.2", + "name": "sebastian/comparator", + "version": "6.3.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/85c77556683e6eee4323e4c5468641ca0237e2e8", + "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8", "shasum": "" }, "require": { - "php": ">=8.2" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "6.3-dev" } }, "autoload": { @@ -4087,103 +1529,71 @@ "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": [ + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:10:34+00:00" - }, - { - "name": "sebastian/type", - "version": "5.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", - "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.1-dev" + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" ], - "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.2" + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" } ], - "time": "2025-03-18T13:35:50+00:00" + "time": "2025-08-10T08:07:46+00:00" }, { - "name": "sebastian/version", - "version": "5.0.2", + "name": "sebastian/complexity", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "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": "5.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -4202,12 +1612,12 @@ "role": "lead" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", "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" + "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": [ { @@ -4215,1067 +1625,874 @@ "type": "github" } ], - "time": "2024-10-09T05:16:32+00:00" + "time": "2024-07-03T04:49:50+00:00" }, { - "name": "slevomat/coding-standard", - "version": "8.18.1", + "name": "sebastian/diff", + "version": "6.0.2", "source": { "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "06b18b3f64979ab31d27c37021838439f3ed5919" + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/06b18b3f64979ab31d27c37021838439f3ed5919", - "reference": "06b18b3f64979ab31d27c37021838439f3ed5919", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", "shasum": "" }, "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", - "php": "^7.4 || ^8.0", - "phpstan/phpdoc-parser": "^2.1.0", - "squizlabs/php_codesniffer": "^3.13.0" + "php": ">=8.2" }, "require-dev": { - "phing/phing": "3.0.1", - "php-parallel-lint/php-parallel-lint": "1.4.0", - "phpstan/phpstan": "2.1.17", - "phpstan/phpstan-deprecation-rules": "2.0.3", - "phpstan/phpstan-phpunit": "2.0.6", - "phpstan/phpstan-strict-rules": "2.0.4", - "phpunit/phpunit": "9.6.8|10.5.45|11.4.4|11.5.21|12.1.3" + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" }, - "type": "phpcodesniffer-standard", + "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "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": [ - "dev", - "phpcs" + "diff", + "udiff", + "unidiff", + "unified diff" ], "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.18.1" + "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/kukulich", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" } ], - "time": "2025-05-22T14:32:30+00:00" + "time": "2024-07-03T04:53:05+00:00" }, { - "name": "spatie/array-to-xml", - "version": "3.4.0", + "name": "sebastian/environment", + "version": "7.2.1", "source": { "type": "git", - "url": "https://github.com/spatie/array-to-xml.git", - "reference": "7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67" + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67", - "reference": "7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", "shasum": "" }, "require": { - "ext-dom": "*", - "php": "^8.0" + "php": ">=8.2" }, "require-dev": { - "mockery/mockery": "^1.2", - "pestphp/pest": "^1.21", - "spatie/pest-plugin-snapshots": "^1.1" + "phpunit/phpunit": "^11.3" + }, + "suggest": { + "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.x-dev" + "dev-main": "7.2-dev" } }, "autoload": { - "psr-4": { - "Spatie\\ArrayToXml\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://freek.dev", - "role": "Developer" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Convert an array to xml", - "homepage": "https://github.com/spatie/array-to-xml", + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ - "array", - "convert", - "xml" + "Xdebug", + "environment", + "hhvm" ], "support": { - "source": "https://github.com/spatie/array-to-xml/tree/3.4.0" + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" }, "funding": [ { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" + "url": "https://github.com/sebastianbergmann", + "type": "github" }, { - "url": "https://github.com/spatie", - "type": "github" + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" } ], - "time": "2024-12-16T12:45:15+00:00" + "time": "2025-05-21T11:55:47+00:00" }, { - "name": "squizlabs/php_codesniffer", - "version": "3.13.0", + "name": "sebastian/exporter", + "version": "6.3.2", "source": { "type": "git", - "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "65ff2489553b83b4597e89c3b8b721487011d186" + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/65ff2489553b83b4597e89c3b8b721487011d186", - "reference": "65ff2489553b83b4597e89c3b8b721487011d186", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", "shasum": "" }, "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" + "phpunit/phpunit": "^11.3" }, - "bin": [ - "bin/phpcbf", - "bin/phpcs" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "3.x-dev" + "dev-main": "6.3-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { - "name": "Greg Sherwood", - "role": "Former lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "Current lead" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" }, { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", - "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", - "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" - }, - "funding": [ - { - "url": "https://github.com/PHPCSStandards", - "type": "github" + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" }, { - "url": "https://github.com/jrfnl", - "type": "github" + "name": "Volker Dusch", + "email": "github@wallbash.com" }, { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" + "name": "Adam Harvey", + "email": "aharvey@php.net" }, { - "url": "https://thanks.dev/u/gh/phpcsstandards", - "type": "thanks_dev" + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], - "time": "2025-05-11T03:36:00+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", + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ - "static analysis" + "export", + "exporter" ], "support": { - "issues": "https://github.com/staabm/side-effects-detector/issues", - "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" }, "funding": [ { - "url": "https://github.com/staabm", + "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" } ], - "time": "2024-10-20T05:08:20+00:00" + "time": "2025-09-24T06:12:51+00:00" }, { - "name": "symfony/console", - "version": "v7.2.6", + "name": "sebastian/global-state", + "version": "7.0.2", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218" + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218", - "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", "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" + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.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" + "ext-dom": "*", + "phpunit/phpunit": "^11.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ - "cli", - "command-line", - "console", - "terminal" + "global state" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.2.6" + "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://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2025-04-07T19:09:28+00:00" + "time": "2024-07-03T04:57:36+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "v3.6.0", + "name": "sebastian/lines-of-code", + "version": "3.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", "shasum": "" }, "require": { - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.0-dev" } }, "autoload": { - "files": [ - "function.php" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2024-07-03T04:58:38+00:00" }, { - "name": "symfony/filesystem", - "version": "v7.2.0", + "name": "sebastian/object-enumerator", + "version": "6.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", - "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "symfony/process": "^6.4|^7.0" + "phpunit/phpunit": "^11.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.2.0" + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-10-25T15:15:23+00:00" + "time": "2024-07-03T05:00:13+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.32.0", + "name": "sebastian/object-reflector", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { - "php": ">=7.2" - }, - "provide": { - "ext-ctype": "*" + "php": ">=8.2" }, - "suggest": { - "ext-ctype": "For best performance" + "require-dev": { + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" + "branch-alias": { + "dev-main": "4.0-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-07-03T05:01:32+00:00" }, { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.32.0", + "name": "sebastian/recursion-context", + "version": "6.0.3", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=8.2" }, - "suggest": { - "ext-intl": "For best performance" + "require-dev": { + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" + "branch-alias": { + "dev-main": "6.0-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" + "url": "https://github.com/sebastianbergmann", + "type": "github" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2025-08-13T04:42:22+00:00" }, { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.32.0", + "name": "sebastian/type", + "version": "5.1.3", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "3833d7255cc303546435cb650316bff708a1c75c" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", - "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=8.2" }, - "suggest": { - "ext-intl": "For best performance" + "require-dev": { + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" + "branch-alias": { + "dev-main": "5.1-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, "classmap": [ - "Resources/stubs" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.3" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" + "url": "https://github.com/sebastianbergmann", + "type": "github" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2025-08-09T06:55:48+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.32.0", + "name": "sebastian/version", + "version": "5.0.2", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", "shasum": "" }, "require": { - "ext-iconv": "*", - "php": ">=7.2" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" + "php": ">=8.2" }, "type": "library", "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" + "branch-alias": { + "dev-main": "5.0-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-12-23T08:48:59+00:00" + "time": "2024-10-09T05:16:32+00:00" }, { - "name": "symfony/polyfill-php84", - "version": "v1.32.0", + "name": "slevomat/coding-standard", + "version": "8.22.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "000df7860439609837bbe28670b0be15783b7fbf" + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "1dd80bf3b93692bedb21a6623c496887fad05fec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/000df7860439609837bbe28670b0be15783b7fbf", - "reference": "000df7860439609837bbe28670b0be15783b7fbf", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/1dd80bf3b93692bedb21a6623c496887fad05fec", + "reference": "1dd80bf3b93692bedb21a6623c496887fad05fec", "shasum": "" }, "require": { - "php": ">=7.2" + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.1.2", + "php": "^7.4 || ^8.0", + "phpstan/phpdoc-parser": "^2.3.0", + "squizlabs/php_codesniffer": "^3.13.4" }, - "type": "library", + "require-dev": { + "phing/phing": "3.0.1|3.1.0", + "php-parallel-lint/php-parallel-lint": "1.4.0", + "phpstan/phpstan": "2.1.24", + "phpstan/phpstan-deprecation-rules": "2.0.3", + "phpstan/phpstan-phpunit": "2.0.7", + "phpstan/phpstan-strict-rules": "2.0.6", + "phpunit/phpunit": "9.6.8|10.5.48|11.4.4|11.5.36|12.3.10" + }, + "type": "phpcodesniffer-standard", "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" + "branch-alias": { + "dev-master": "8.x-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php84\\": "" - }, - "classmap": [ - "Resources/stubs" - ] + "SlevomatCodingStandard\\": "SlevomatCodingStandard/" + } }, "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 backporting some PHP 8.4+ features to lower PHP versions", - "homepage": "https://symfony.com", + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "dev", + "phpcs" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.32.0" + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/8.22.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/kukulich", "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", "type": "tidelift" } ], - "time": "2025-02-20T12:04:08+00:00" + "time": "2025-09-13T08:53:30+00:00" }, { - "name": "symfony/service-contracts", - "version": "v3.6.0", + "name": "squizlabs/php_codesniffer", + "version": "3.13.4", "source": { "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "ad545ea9c1b7d270ce0fc9cbfb884161cd706119" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", - "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ad545ea9c1b7d270ce0fc9cbfb884161cd706119", + "reference": "ad545ea9c1b7d270ce0fc9cbfb884161cd706119", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.5|^3" + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" }, - "conflict": { - "ext-psr": "<1.1|>=2" + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], "type": "library", "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-master": "3.x-dev" } }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Greg Sherwood", + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "phpcs", + "standards", + "static analysis" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" + "url": "https://github.com/PHPCSStandards", + "type": "github" }, { - "url": "https://github.com/fabpot", + "url": "https://github.com/jrfnl", "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2025-04-25T09:37:31+00:00" + "time": "2025-09-05T05:47:09+00:00" }, { - "name": "symfony/string", - "version": "v7.2.6", + "name": "staabm/side-effects-detector", + "version": "1.0.5", "source": { "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931" + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931", - "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/translation-contracts": "<2.5" + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" }, "require-dev": { - "symfony/emoji": "^7.1", - "symfony/error-handler": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", - "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" + "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": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "lib/" ] }, "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": "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", + "description": "A static analysis tool to detect side effects in PHP code", "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" + "static analysis" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.2.6" + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/staabm", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2025-04-20T20:18:16+00:00" + "time": "2024-10-20T05:08:20+00:00" }, { "name": "theseer/tokenizer", @@ -5327,124 +2544,6 @@ ], "time": "2024-03-03T12:36:25+00:00" }, - { - "name": "vimeo/psalm", - "version": "6.11.0", - "source": { - "type": "git", - "url": "https://github.com/vimeo/psalm.git", - "reference": "4ed53b7ccebc09ef60ec4c9e464bf8a01bfd35b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/4ed53b7ccebc09ef60ec4c9e464bf8a01bfd35b0", - "reference": "4ed53b7ccebc09ef60ec4c9e464bf8a01bfd35b0", - "shasum": "" - }, - "require": { - "amphp/amp": "^3", - "amphp/byte-stream": "^2", - "amphp/parallel": "^2.3", - "composer-runtime-api": "^2", - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^2.0 || ^3.0", - "danog/advanced-json-rpc": "^3.1", - "dnoegel/php-xdg-base-dir": "^0.1.1", - "ext-ctype": "*", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-simplexml": "*", - "ext-tokenizer": "*", - "felixfbecker/language-server-protocol": "^1.5.3", - "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0", - "netresearch/jsonmapper": "^5.0", - "nikic/php-parser": "^5.0.0", - "php": "~8.1.31 || ~8.2.27 || ~8.3.16 || ~8.4.3", - "sebastian/diff": "^4.0 || ^5.0 || ^6.0 || ^7.0", - "spatie/array-to-xml": "^2.17.0 || ^3.0", - "symfony/console": "^6.0 || ^7.0", - "symfony/filesystem": "~6.3.12 || ~6.4.3 || ^7.0.3", - "symfony/polyfill-php84": "^1.31.0" - }, - "provide": { - "psalm/psalm": "self.version" - }, - "require-dev": { - "amphp/phpunit-util": "^3", - "bamarni/composer-bin-plugin": "^1.4", - "brianium/paratest": "^6.9", - "danog/class-finder": "^0.4.8", - "dg/bypass-finals": "^1.5", - "ext-curl": "*", - "mockery/mockery": "^1.5", - "nunomaduro/mock-final-classes": "^1.1", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpdoc-parser": "^1.6", - "phpunit/phpunit": "^9.6", - "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.19", - "slevomat/coding-standard": "^8.4", - "squizlabs/php_codesniffer": "^3.6", - "symfony/process": "^6.0 || ^7.0" - }, - "suggest": { - "ext-curl": "In order to send data to shepherd", - "ext-igbinary": "^2.0.5 is required, used to serialize caching data" - }, - "bin": [ - "psalm", - "psalm-language-server", - "psalm-plugin", - "psalm-refactor", - "psalm-review", - "psalter" - ], - "type": "project", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev", - "dev-2.x": "2.x-dev", - "dev-3.x": "3.x-dev", - "dev-4.x": "4.x-dev", - "dev-5.x": "5.x-dev", - "dev-6.x": "6.x-dev", - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psalm\\": "src/Psalm/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthew Brown" - }, - { - "name": "Daniil Gentili", - "email": "daniil@daniil.it" - } - ], - "description": "A static analysis tool for finding errors in PHP applications", - "keywords": [ - "code", - "inspection", - "php", - "static analysis" - ], - "support": { - "docs": "https://psalm.dev/docs", - "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm" - }, - "time": "2025-05-12T11:30:26+00:00" - }, { "name": "webimpress/coding-standard", "version": "1.4.0", @@ -5499,77 +2598,15 @@ } ], "time": "2024-10-16T06:55:17+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" } ], "aliases": [], "minimum-stability": "dev", - "stability-flags": { - "laminas/laminas-db": 20 - }, + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", - "ext-pdo": "*", - "ext-pdo_pgsql": "*" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0" }, "platform-dev": {}, "platform-overrides": { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..096cae4 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,2 @@ +parameters: + ignoreErrors: diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..4b4e3f6 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,17 @@ +includes: + - phpstan-baseline.neon +parameters: + level: 5 + paths: + - src + - test + universalObjectCratesClasses: + - Laminas\Stdlib\ArrayObject + stubFiles: + - stubs/Laminas/ServiceManager/Factory/AbstractFactoryInterface.stub + - stubs/Laminas/ServiceManager/Factory/DelegatorFactoryInterface.stub + - stubs/Laminas/ServiceManager/Factory/FactoryInterface.stub + - stubs/Laminas/ServiceManager/Factory/InvokableFactory.stub + - stubs/Laminas/ServiceManager/Initializer/InitializerInterface.stub + - stubs/Psr/Container/ContainerInterface.stub + treatPhpDocTypesAsCertain: false \ No newline at end of file diff --git a/psalm-baseline.xml b/psalm-baseline.xml deleted file mode 100644 index 94fc6ab..0000000 --- a/psalm-baseline.xml +++ /dev/null @@ -1,1063 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - has(ProfilerInterface::class) ? $container->get(ProfilerInterface::class) : null]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - resource : $resultResource]]> - - - - resource->insert_id]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - resource->connect_error]]> - - - - - - - - - - - - - resource instanceof \mysqli]]> - resource instanceof \mysqli]]> - - - - resource->connect_error]]> - - - - - - - - - - - - - - - - - - - connection->getResource()]]> - - - - - - - - - - - - - - - - - - - - - - - - - - get('config')['db']]]> - - - - - - - - - - - - - - - - resource->affected_rows]]> - resource->num_rows]]> - resource->num_rows]]> - - - - - - - - - - - - - resource->error]]> - statementBindValues['keys']]]> - - - statementBindValues['keys'][$i]]]> - statementBindValues['values'][$i]]]> - - - currentData[$this->statementBindValues['keys'][$i]]]]> - - - currentData[$this->statementBindValues['keys'][$i]]]]> - - - - - - - - - - - - name]]> - - - resource->num_rows]]> - - - - - - - - - - - - - - - resource->error]]> - resource->num_rows]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - profiler]]> - - - profiler]]> - - - - - - - - - driver]]> - - - - - - - - - - - - - - - - - - - - - - connectionParameters]]> - connectionParameters]]> - - - - - - - - - driver->createStatement($sql)]]> - - - - - - - - - resource->getAttribute(\PDO::ATTR_DRIVER_NAME)]]> - resource->getAttribute(\PDO::ATTR_DRIVER_NAME)]]> - - - - - - - - dsn]]> - - - - - - - fetchColumn()]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - resource]]> - - - - - - - - - - - - - - - - - - - - connection->getResource()]]> - - - - - - - - - - - - - - - - - - - - features[$name]]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - get('config')['db']]]> - - - get('config')['db']]]> - - - - - - - - rowCount instanceof Closure]]> - rowCount)]]> - - - - resource->rowCount()]]> - rowCount)]]> - - - - - - - - - - - - - - - - rowCount;]]> - - - - - - - - - - resource->rowCount()]]> - - - - - - - - - - - resource]]> - - - - - - driver->createResult($this->resource, $this)]]> - - - - - - - - - - - - - - - resource->errorInfo()]]> - - - - - - - - - - - - - - - - - - - - - - - - profiler]]> - - - parameterContainer]]> - profiler]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - processInfo['paramPrefix']]]> - processInfo['paramPrefix']]]> - - - limit]]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - variables]]> - variables]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - adapter]]> - adapter]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - adapter]]> - - - - - - - - - - - - - - - - - - - - - current()]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $key]]> - $key]]> - id]]> - name]]> - value]]> - - - - - - adapter]]> - adapter]]> - adapter]]> - adapter]]> - adapter]]> - adapter]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - fixtureFile)]]> - - - - - - - - - - - - - - - - - - - - - - - diff --git a/psalm.xml.dist b/psalm.xml.dist deleted file mode 100644 index 86d649b..0000000 --- a/psalm.xml.dist +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/psr-container.php.stub b/psr-container.php.stub deleted file mode 100644 index 1a59597..0000000 --- a/psr-container.php.stub +++ /dev/null @@ -1,23 +0,0 @@ - $id - * @psalm-return ($id is class-string ? T : mixed) - */ - public function get(string $id): mixed; - } -} \ No newline at end of file diff --git a/renovate.json b/renovate.json index 580e320..0c9fe21 100644 --- a/renovate.json +++ b/renovate.json @@ -1,6 +1,6 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ - "local>axleus/.github:renovate-config" + "local>php-db/.github:renovate-config" ] } \ No newline at end of file diff --git a/src/Adapter.php b/src/Adapter.php deleted file mode 100644 index 38e6a53..0000000 --- a/src/Adapter.php +++ /dev/null @@ -1,17 +0,0 @@ - Platform\Postgresql::class, ], 'factories' => [ - AdapterInterface::class => AdapterServiceFactory::class, - DriverInterface::class => Driver\Pdo\DriverFactory::class, - Platform\Postgresql::class => InvokableFactory::class, + AdapterInterface::class => AdapterServiceFactory::class, + DriverInterface::class => Driver\Pdo\DriverFactory::class, + Platform\Postgresql::class => InvokableFactory::class, ], ]; } diff --git a/src/AdapterServiceFactory.php b/src/Container/AdapterServiceFactory.php similarity index 79% rename from src/AdapterServiceFactory.php rename to src/Container/AdapterServiceFactory.php index c936e1f..788b86c 100644 --- a/src/AdapterServiceFactory.php +++ b/src/Container/AdapterServiceFactory.php @@ -1,16 +1,17 @@ (new ConfigProvider())->getDependencies(), - ]; - } -} diff --git a/src/Platform/Postgresql.php b/src/Platform/Postgresql.php index 182c63b..ffd2efe 100644 --- a/src/Platform/Postgresql.php +++ b/src/Platform/Postgresql.php @@ -1,15 +1,15 @@ |null $options + */ + public function __invoke( + ContainerInterface $container, + string $name, + callable $callback, + ?array $options = null + ): mixed; +} diff --git a/stubs/Laminas/ServiceManager/Factory/FactoryInterface.stub b/stubs/Laminas/ServiceManager/Factory/FactoryInterface.stub new file mode 100644 index 0000000..e1d6ac5 --- /dev/null +++ b/stubs/Laminas/ServiceManager/Factory/FactoryInterface.stub @@ -0,0 +1,21 @@ +|null $options + */ + public function __invoke(ContainerInterface $container, string $requestedName, ?array $options = null): mixed; +} diff --git a/stubs/Laminas/ServiceManager/Factory/InvokableFactory.stub b/stubs/Laminas/ServiceManager/Factory/InvokableFactory.stub new file mode 100644 index 0000000..47d7303 --- /dev/null +++ b/stubs/Laminas/ServiceManager/Factory/InvokableFactory.stub @@ -0,0 +1,22 @@ +|null $options + */ + public function __invoke(ContainerInterface $container, string $requestedName, ?array $options = null): mixed + { + return null === $options ? new $requestedName() : new $requestedName($options); + } +} diff --git a/stubs/Laminas/ServiceManager/Initializer/InitializerInterface.stub b/stubs/Laminas/ServiceManager/Initializer/InitializerInterface.stub new file mode 100644 index 0000000..345c9a3 --- /dev/null +++ b/stubs/Laminas/ServiceManager/Initializer/InitializerInterface.stub @@ -0,0 +1,19 @@ + Date: Sun, 28 Sep 2025 02:46:05 -0500 Subject: [PATCH 3/9] fix composer package name and support info Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- composer.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 483e2b2..740a95e 100644 --- a/composer.json +++ b/composer.json @@ -1,17 +1,17 @@ { - "name": "laminas/laminas-db-adapter-pgsql", - "description": "SQLite support for laminas-db", + "name": "php-db/phpdb-adapter-pgsql", + "description": "PostgreSQL support for php-db", "license": "BSD-3-Clause", "keywords": [ - "laminas", + "php-db", "pgsql", "db" ], - "homepage": "https://github.com/axleus/laminas-db-adapter-pgsql/discussions", + "homepage": "https://php-db.dev", "support": { - "issues": "https://github.com/alxeus/laminas-db-adapter-pgsql/issues", - "source": "https://github.com/axleus/laminas-db-adapter-pgsql", - "forum": "https://github.com/axleus/laminas-db-adapter-pgsql/discussions" + "issues": "https://github.com/php-db/phpdb-adapter-pgsql/issues", + "source": "https://github.com/php-db/phpdb-adapter-pgsql", + "forum": "https://github.com/php-db/phpdb-adapter-pgsql/discussions" }, "minimum-stability": "dev", "prefer-stable": true, From 69168f8733ac9ec6ca12dd3edbb81c1adc382a6c Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Sun, 28 Sep 2025 21:14:48 -0500 Subject: [PATCH 4/9] Update composer.lock and fix docker build. Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- composer.lock | 14 +++++++------- docker/databases/pgsql/Dockerfile | 3 --- docker/databases/postgresql/Dockerfile | 4 ++++ 3 files changed, 11 insertions(+), 10 deletions(-) delete mode 100644 docker/databases/pgsql/Dockerfile create mode 100644 docker/databases/postgresql/Dockerfile diff --git a/composer.lock b/composer.lock index 26eaed0..992d1a4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c8dc357412a66d28ec86e4bfc2d6a17a", + "content-hash": "4a3049b922cefbc90e1f498dd0fdca74", "packages": [ { "name": "brick/varexporter", @@ -1200,16 +1200,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.5.41", + "version": "11.5.42", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "b42782bcb947d2c197aea42ce9714ee2d974b283" + "reference": "1c6cb5dfe412af3d0dfd414cfd110e3b9cfdbc3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b42782bcb947d2c197aea42ce9714ee2d974b283", - "reference": "b42782bcb947d2c197aea42ce9714ee2d974b283", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1c6cb5dfe412af3d0dfd414cfd110e3b9cfdbc3c", + "reference": "1c6cb5dfe412af3d0dfd414cfd110e3b9cfdbc3c", "shasum": "" }, "require": { @@ -1281,7 +1281,7 @@ "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.41" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.42" }, "funding": [ { @@ -1305,7 +1305,7 @@ "type": "tidelift" } ], - "time": "2025-09-24T06:32:10+00:00" + "time": "2025-09-28T12:09:13+00:00" }, { "name": "sebastian/cli-parser", diff --git a/docker/databases/pgsql/Dockerfile b/docker/databases/pgsql/Dockerfile deleted file mode 100644 index 69c3f20..0000000 --- a/docker/databases/pgsql/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -ARG VERSION=8.4.5 - -FROM mysql:${VERSION}-bookworm AS base \ No newline at end of file diff --git a/docker/databases/postgresql/Dockerfile b/docker/databases/postgresql/Dockerfile new file mode 100644 index 0000000..c4609c2 --- /dev/null +++ b/docker/databases/postgresql/Dockerfile @@ -0,0 +1,4 @@ +ARG VERSION=17.4 +ARG ALPINE_VERSION=3.21 + +FROM postgres:${VERSION}-alpine${ALPINE_VERSION} AS base \ No newline at end of file From c09a653dc93dd5ed48561d0b0abe66b0629ff05e Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Mon, 29 Sep 2025 01:34:32 -0500 Subject: [PATCH 5/9] Continues code alignment Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- phpcs.xml.dist | 27 +++++ src/Driver/Pdo/Connection.php | 2 + src/Driver/Pdo/Pdo.php | 75 ++------------ src/Driver/Pdo/Result.php | 9 -- src/Driver/Pdo/Statement.php | 9 -- src/Driver/Pgsql/Connection.php | 36 +++---- src/Driver/Pgsql/Pgsql.php | 171 ++++++++++---------------------- 7 files changed, 105 insertions(+), 224 deletions(-) create mode 100644 phpcs.xml.dist delete mode 100644 src/Driver/Pdo/Result.php delete mode 100644 src/Driver/Pdo/Statement.php diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..38effcf --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + src + test + + + + + + + diff --git a/src/Driver/Pdo/Connection.php b/src/Driver/Pdo/Connection.php index d8d0d20..d915ca0 100644 --- a/src/Driver/Pdo/Connection.php +++ b/src/Driver/Pdo/Connection.php @@ -1,5 +1,7 @@ statementPrototype = $statementPrototype->setDriver($this); - } - /** - * Register result prototype + * @param PDOStatement $resource */ - public function registerResultPrototype(ResultInterface $resultPrototype): void - { - $this->resultPrototype = $resultPrototype; - } - - /** - * Setup the default features for Pdo - * - * @return $this Provides a fluent interface - */ - public function setupDefaultFeatures(): static - { - return $this; - } - - /** - * Register connection - * - * @return $this Provides a fluent interface - */ - public function registerConnection(PDOConnection|ConnectionInterface $connection): static - { - $this->connection = $connection->setDriver($this); - - return $this; - } - #[Override] - /** - * @param resource $resource - * @param mixed $context - * @return \PhpDb\Adapter\Driver\Pdo\Result - */ - public function createResult($resource, $context = null): Result + public function createResult($resource, $context = null): ResultInterface { - $result = clone $this->resultPrototype; + /** @var Result $result */ + $result = clone $this->resultPrototype; $result->initialize($resource, $this->connection->getLastGeneratedValue()); return $result; diff --git a/src/Driver/Pdo/Result.php b/src/Driver/Pdo/Result.php deleted file mode 100644 index 518cfa7..0000000 --- a/src/Driver/Pdo/Result.php +++ /dev/null @@ -1,9 +0,0 @@ -setConnectionParameters($connectionInfo); @@ -50,13 +50,7 @@ public function __construct(PgSqlConnection|array $connectionInfo = null) } } - /** - * Set resource - * - * @param PgSqlConnection $resource - * @return $this Provides a fluent interface - */ - public function setResource(PgSqlConnection $resource): static + public function setResource(PgSqlConnection $resource): ConnectionInterface { $this->resource = $resource; @@ -64,11 +58,9 @@ public function setResource(PgSqlConnection $resource): static } /** - * Set driver - * - * @return $this Provides a fluent interface + * old param type hint Pgsql $driver */ - public function setDriver(Pgsql $driver): static + public function setDriver(DriverInterface $driver): DriverAwareInterface { $this->driver = $driver; diff --git a/src/Driver/Pgsql/Pgsql.php b/src/Driver/Pgsql/Pgsql.php index 4f0b628..40b559c 100644 --- a/src/Driver/Pgsql/Pgsql.php +++ b/src/Driver/Pgsql/Pgsql.php @@ -1,144 +1,91 @@ false, ]; - /** - * Constructor - * - * @param array|Connection|resource $connection - * @param array $options - */ public function __construct( - $connection, - ?Statement $statementPrototype = null, - ?Result $resultPrototype = null, - $options = null + protected readonly ConnectionInterface&Connection $connection, + protected readonly StatementInterface&Statement $statementPrototype, + protected readonly ResultInterface $resultPrototype, + array $options = [] ) { - if (! $connection instanceof Connection) { - $connection = new Connection($connection); - } + $this->checkEnvironment(); + + //todo: verify this usage + $options = array_intersect_key(array_merge($this->options, $options), $this->options); - $this->registerConnection($connection); - $this->registerStatementPrototype($statementPrototype ?: new Statement()); - $this->registerResultPrototype($resultPrototype ?: new Result()); + if ($this->connection instanceof DriverAwareInterface) { + $this->connection->setDriver($this); + } + if ($this->statementPrototype instanceof DriverAwareInterface) { + $this->statementPrototype->setDriver($this); + } } - /** - * @return $this Provides a fluent interface - */ - public function setProfiler(Profiler\ProfilerInterface $profiler): static + #[Override] + public function setProfiler(ProfilerInterface $profiler): ProfilerAwareInterface { $this->profiler = $profiler; - - if ($this->connection instanceof Profiler\ProfilerAwareInterface) { + if ($this->connection instanceof ProfilerAwareInterface) { $this->connection->setProfiler($profiler); } - if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) { + if ($this->statementPrototype instanceof ProfilerAwareInterface) { $this->statementPrototype->setProfiler($profiler); } return $this; } - /** - * @return null|Profiler\ProfilerInterface - */ - public function getProfiler() + #[Override] + public function getProfiler(): ?ProfilerInterface { return $this->profiler; } - /** - * Register connection - * - * @return $this Provides a fluent interface - */ - public function registerConnection(Connection $connection) - { - $this->connection = $connection; - $this->connection->setDriver($this); - - return $this; - } - - /** - * Register statement prototype - * - * @return $this Provides a fluent interface - */ - public function registerStatementPrototype(Statement $statement) - { - $this->statementPrototype = $statement; - $this->statementPrototype->setDriver($this); // needs access to driver to createResult() - - return $this; - } - - /** - * Register result prototype - * - * @return $this Provides a fluent interface - */ - public function registerResultPrototype(Result $result) - { - $this->resultPrototype = $result; - - return $this; - } - - /** - * Check environment - * - * @throws Exception\RuntimeException - * @return void - */ - public function checkEnvironment() + #[Override] + public function checkEnvironment(): bool { if (! extension_loaded('pgsql')) { throw new Exception\RuntimeException( 'The PostgreSQL (pgsql) extension is required for this adapter but the extension is not loaded' ); } + return true; } - /** - * Get connection - * - * @return Connection - */ - public function getConnection() + #[Override] + public function getConnection(): ConnectionInterface&Connection { return $this->connection; } @@ -146,10 +93,10 @@ public function getConnection() /** * Create statement * - * @param string|null $sqlOrResource - * @return Statement + * @param resource|string|null $sqlOrResource */ - public function createStatement($sqlOrResource = null) + #[Override] + public function createStatement($sqlOrResource = null): StatementInterface&Statement { $statement = clone $this->statementPrototype; @@ -169,54 +116,40 @@ public function createStatement($sqlOrResource = null) /** * Create result * - * @param PgSqlResult|PgSqlConnection $resource - * @return Result + * @param resource|PgSqlResult|PgSqlConnection $resource */ - public function createResult($resource) + #[Override] + public function createResult($resource): ResultInterface&Result { + /** @var Result $result */ $result = clone $this->resultPrototype; $result->initialize($resource, $this->connection->getLastGeneratedValue()); return $result; } - /** - * @return Result - */ - public function getResultPrototype() + public function getResultPrototype(): ResultInterface&Result { return $this->resultPrototype; } - /** - * Get prepare Type - * - * @return string - */ - public function getPrepareType() + #[Override] + public function getPrepareType(): string { return self::PARAMETERIZATION_POSITIONAL; } - /** - * Format parameter name - * - * @param string $name - * @param mixed $type - * @return string - */ - public function formatParameterName($name, $type = null) + #[Override] + public function formatParameterName(string $name, ?string $type = null): string { return '$#'; } /** * Get last generated value - * - * @param string $name - * @return mixed */ - public function getLastGeneratedValue($name = null) + #[Override] + public function getLastGeneratedValue(?string $name = null): int|string|false|null { return $this->connection->getLastGeneratedValue($name); } From 9907ccbdc0b7fd333f0df475d74c9e611c9e31b4 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Tue, 30 Sep 2025 14:37:16 -0500 Subject: [PATCH 6/9] PhpCS fixes mostly Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- src/ConfigProvider.php | 8 +- src/Container/AdapterServiceFactory.php | 26 ++- src/Container/PdoDriverInterfaceFactory.php | 23 ++ src/Driver/DatabasePlatformNameTrait.php | 3 - src/Driver/Pdo/Connection.php | 210 ++---------------- src/Driver/Pdo/DriverFactory.php | 17 -- src/Driver/Pdo/Pdo.php | 2 +- src/Driver/Pgsql/Connection.php | 12 +- src/Driver/Pgsql/Pgsql.php | 1 - src/Driver/Pgsql/PgsqlConfig.php | 15 +- src/Driver/Pgsql/Result.php | 59 ++--- src/Driver/Pgsql/Statement.php | 21 +- src/Platform/Postgresql.php | 11 +- .../Driver/Pdo/Postgresql/AdapterTrait.php | 11 +- .../Pdo/Postgresql/TableGatewayTest.php | 2 +- .../Adapter/Platform/PostgresqlTest.php | 4 +- .../Adapter/AdapterServiceFactoryTest.php | 29 +-- test/unit/Adapter/AdapterTest.php | 63 +++--- test/unit/Adapter/ConfigProviderTest.php | 22 +- test/unit/Adapter/ModuleTest.php | 42 ---- 20 files changed, 167 insertions(+), 414 deletions(-) create mode 100644 src/Container/PdoDriverInterfaceFactory.php delete mode 100644 src/Driver/Pdo/DriverFactory.php delete mode 100644 test/unit/Adapter/ModuleTest.php diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index 8644cfe..19aa7af 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -21,14 +21,14 @@ public function __invoke(): array public function getDependencies(): array { return [ - 'aliases' => [ + 'aliases' => [ PlatformInterface::class => Platform\Postgresql::class, ], 'factories' => [ - AdapterInterface::class => AdapterServiceFactory::class, - DriverInterface::class => Driver\Pdo\DriverFactory::class, + AdapterInterface::class => Container\AdapterServiceFactory::class, + DriverInterface::class => Container\PdoDriverInterfaceFactory::class, Platform\Postgresql::class => InvokableFactory::class, ], ]; } -} \ No newline at end of file +} diff --git a/src/Container/AdapterServiceFactory.php b/src/Container/AdapterServiceFactory.php index 788b86c..e22113d 100644 --- a/src/Container/AdapterServiceFactory.php +++ b/src/Container/AdapterServiceFactory.php @@ -2,11 +2,14 @@ declare(strict_types=1); -namespace PhpDb\Adapter\Pgsql; +namespace PhpDb\Adapter\Pgsql\Container; +use Laminas\ServiceManager\Factory\FactoryInterface; +use PhpDb\Adapter\Adapter; use PhpDb\Adapter\Driver\DriverInterface; +use PhpDb\Adapter\Pgsql\Platform; +use PhpDb\Adapter\Profiler\ProfilerInterface; use PhpDb\ResultSet\ResultSetInterface; -use Laminas\ServiceManager\Factory\FactoryInterface; use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; @@ -16,17 +19,20 @@ class AdapterServiceFactory implements FactoryInterface /** * Create db adapter service * - * @param ContainerInterface $container - * @param string $requestedName * @param array|null $options * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface - * @return Adapter */ - public function __invoke(ContainerInterface $container, string $requestedName, ?array $options = null): Adapter - { - $resultSetPrototype = $container->has(ResultSetInterface::class) ? $container->get(ResultSetInterface::class) : null; - $profiler = $this->createProfiler($container, $config['db']['profiler'] ?? []); + public function __invoke( + ContainerInterface $container, + string $requestedName, + ?array $options = null + ): Adapter { + $resultSetPrototype = $container->has(ResultSetInterface::class) + ? $container->get(ResultSetInterface::class) + : null; + + $profiler = $container->get(ProfilerInterface::class); return new Adapter( $container->get(DriverInterface::class), @@ -35,4 +41,4 @@ public function __invoke(ContainerInterface $container, string $requestedName, ? $profiler ); } -} \ No newline at end of file +} diff --git a/src/Container/PdoDriverInterfaceFactory.php b/src/Container/PdoDriverInterfaceFactory.php new file mode 100644 index 0000000..b82b94b --- /dev/null +++ b/src/Container/PdoDriverInterfaceFactory.php @@ -0,0 +1,23 @@ +get('config')['db']); + } +} diff --git a/src/Driver/DatabasePlatformNameTrait.php b/src/Driver/DatabasePlatformNameTrait.php index afd0aab..a940404 100644 --- a/src/Driver/DatabasePlatformNameTrait.php +++ b/src/Driver/DatabasePlatformNameTrait.php @@ -8,9 +8,6 @@ trait DatabasePlatformNameTrait { /** * Get database platform name - * - * @param string $nameFormat - * @return string */ public function getDatabasePlatformName(string $nameFormat = self::NAME_FORMAT_CAMELCASE): string { diff --git a/src/Driver/Pdo/Connection.php b/src/Driver/Pdo/Connection.php index d915ca0..3f5de24 100644 --- a/src/Driver/Pdo/Connection.php +++ b/src/Driver/Pdo/Connection.php @@ -4,72 +4,29 @@ namespace PhpDb\Adapter\Pgsql\Driver\Pdo; -use PhpDb\Adapter\Driver\ConnectionInterface; -use PhpDb\Adapter\Driver\Pdo\AbstractPdoConnection; -use PhpDb\Adapter\Driver\PdoDriverInterface; -use PhpDb\Adapter\Driver\ResultInterface; -use PhpDb\Adapter\Driver\StatementInterface; -use PhpDb\Adapter\Exception; -use PhpDb\Adapter\Exception\RunTimeException; +use Override; use PDO; use PDOException; use PDOStatement; +use PhpDb\Adapter\Driver\ConnectionInterface; +use PhpDb\Adapter\Driver\Pdo\AbstractPdoConnection; +use PhpDb\Adapter\Driver\PdoConnectionInterface; +use PhpDb\Adapter\Exception; use function array_diff_key; -use function is_array; use function is_int; use function str_replace; +use function str_starts_with; use function strtolower; use function substr; -class Connection extends AbstractPdoConnection implements ConnectionInterface +class Connection extends AbstractPdoConnection { - /** @var PdoDriverInterface */ - protected PdoDriverInterface $driver; - - /** @var PDO */ - protected $resource; - - /** @var null|string */ - protected ?string $dsn; - - /** - * Constructor - * - * @param PDO|array|null $connectionParameters - * @throws Exception\InvalidArgumentException - */ - public function __construct(PDO|array $connectionParameters = null) - { - parent::__construct($connectionParameters); - - if (is_array($connectionParameters)) { - $this->setConnectionParameters($connectionParameters); - } elseif ($connectionParameters instanceof PDO) { - $this->setResource($connectionParameters); - } elseif (null !== $connectionParameters) { - throw new Exception\InvalidArgumentException( - '$connection must be an array of parameters, a PDO object or null' - ); - } - } - - /** - * Set driver - * - * @return $this Provides a fluent interface - */ - public function setDriver(PdoDriverInterface $driver): static - { - $this->driver = $driver; - - return $this; - } - /** * {@inheritDoc} */ - public function getCurrentSchema(): bool|string + #[Override] + public function getCurrentSchema(): string|bool { if (! $this->isConnected()) { $this->connect(); @@ -86,10 +43,12 @@ public function getCurrentSchema(): bool|string /** * {@inheritDoc} + * * @throws Exception\InvalidConnectionParametersException * @throws Exception\RuntimeException */ - public function connect(): static + #[Override] + public function connect(): ConnectionInterface&PdoConnectionInterface { if ($this->resource) { return $this; @@ -177,107 +136,11 @@ public function connect(): static /** * {@inheritDoc} - */ - public function isConnected(): bool - { - return $this->resource instanceof PDO; - } - - /** - * {@inheritDoc} - */ - public function beginTransaction(): static - { - if (! $this->isConnected()) { - $this->connect(); - } - - if (0 === $this->nestedTransactionsCount) { - $this->resource->beginTransaction(); - $this->inTransaction = true; - } - - $this->nestedTransactionsCount++; - - return $this; - } - - /** - * {@inheritDoc} - */ - public function commit(): static - { - if (! $this->isConnected()) { - $this->connect(); - } - - if ($this->inTransaction) { - $this->nestedTransactionsCount -= 1; - } - - /* - * This shouldn't check for being in a transaction since - * after issuing a SET autocommit=0; we have to commit too. - */ - if (0 === $this->nestedTransactionsCount) { - $this->resource->commit(); - $this->inTransaction = false; - } - - return $this; - } - - /** - * {@inheritDoc} - * @throws Exception\RuntimeException - */ - public function rollback(): static - { - if (! $this->isConnected()) { - throw new Exception\RuntimeException('Must be connected before you can rollback'); - } - - if (! $this->inTransaction()) { - throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback'); - } - - $this->resource->rollBack(); - - $this->inTransaction = false; - $this->nestedTransactionsCount = 0; - - return $this; - } - - /** - * {@inheritDoc} - * @throws Exception\InvalidQueryException - */ - public function execute($sql): ResultInterface - { - if (! $this->isConnected()) { - $this->connect(); - } - - $this->profiler?->profilerStart($sql); - - $resultResource = $this->resource->query($sql); - - $this->profiler?->profilerFinish(); - - if ($resultResource === false) { - $errorInfo = $this->resource->errorInfo(); - throw new Exception\InvalidQueryException($errorInfo[2]); - } - - return $this->driver->createResult($resultResource, $sql); - } - - /** - * {@inheritDoc} + * * @param string $name * @return string|null|false */ + #[Override] public function getLastGeneratedValue($name = null): bool|int|string|null { try { @@ -287,49 +150,4 @@ public function getLastGeneratedValue($name = null): bool|int|string|null return false; } - - /** - * Get the dsn string for this connection - * - * @throws RunTimeException - * @return string - */ - public function getDsn(): string - { - if (! $this->dsn) { - throw new Exception\RuntimeException( - 'The DSN has not been set or constructed from parameters in connect() for this Connection' - ); - } - - return $this->dsn; - } - - /** - * Set resource - * - * @return $this Provides a fluent interface - */ - public function setResource(PDO $resource): static - { - $this->resource = $resource; - $this->driverName = strtolower($this->resource->getAttribute(PDO::ATTR_DRIVER_NAME)); - - return $this; - } - - /** - * Prepare - * - * @param ?string $sql - * @return StatementInterface - */ - public function prepare(?string $sql = null): StatementInterface - { - if (! $this->isConnected()) { - $this->connect(); - } - - return $this->driver->createStatement($sql); - } } diff --git a/src/Driver/Pdo/DriverFactory.php b/src/Driver/Pdo/DriverFactory.php deleted file mode 100644 index 1c00c19..0000000 --- a/src/Driver/Pdo/DriverFactory.php +++ /dev/null @@ -1,17 +0,0 @@ -get('config')['db']); - } -} diff --git a/src/Driver/Pdo/Pdo.php b/src/Driver/Pdo/Pdo.php index bc3a687..1aee71d 100644 --- a/src/Driver/Pdo/Pdo.php +++ b/src/Driver/Pdo/Pdo.php @@ -19,7 +19,7 @@ class Pdo extends AbstractPdo * @param PDOStatement $resource */ #[Override] - public function createResult($resource, $context = null): ResultInterface + public function createResult($resource): ResultInterface { /** @var Result $result */ $result = clone $this->resultPrototype; diff --git a/src/Driver/Pgsql/Connection.php b/src/Driver/Pgsql/Connection.php index 2986a84..03aba23 100644 --- a/src/Driver/Pgsql/Connection.php +++ b/src/Driver/Pgsql/Connection.php @@ -4,7 +4,7 @@ namespace PhpDb\Adapter\Pgsql\Driver\Pgsql; -use Override; +use PgSql\Connection as PgSqlConnection; use PhpDb\Adapter\Driver\AbstractConnection; use PhpDb\Adapter\Driver\ConnectionInterface; use PhpDb\Adapter\Driver\DriverAwareInterface; @@ -12,8 +12,6 @@ use PhpDb\Adapter\Driver\ResultInterface; use PhpDb\Adapter\Exception; use PhpDb\ResultSet\ResultSetInterface; -use PgSql\Connection as PgSqlConnection; -use SebastianBergmann\CodeCoverage\Driver\Driver; use function array_filter; use function http_build_query; @@ -30,7 +28,6 @@ use function str_replace; use function urldecode; -use const PGSQL_CONNECT_ASYNC; use const PGSQL_CONNECT_FORCE_NEW; class Connection extends AbstractConnection implements DriverAwareInterface @@ -68,7 +65,6 @@ public function setDriver(DriverInterface $driver): DriverAwareInterface } /** - * @param int|null $type * @return $this Provides a fluent interface */ public function setType(?int $type): static @@ -86,6 +82,7 @@ public function setType(?int $type): static /** * {@inheritDoc} + * * @return null|string */ public function getCurrentSchema(): bool|string @@ -104,6 +101,7 @@ public function getCurrentSchema(): bool|string /** * {@inheritDoc} + * * @throws Exception\RuntimeException On failure. */ public function connect(): static @@ -224,6 +222,7 @@ public function rollback(): static /** * {@inheritDoc} + * * @throws Exception\InvalidQueryException * @return resource|ResultSetInterface */ @@ -249,6 +248,7 @@ public function execute($sql): ResultInterface /** * {@inheritDoc} + * * @return string */ public function getLastGeneratedValue($name = null): bool|int|string|null @@ -266,8 +266,6 @@ public function getLastGeneratedValue($name = null): bool|int|string|null /** * Get Connection String - * - * @return string */ private function getConnectionString(): string { diff --git a/src/Driver/Pgsql/Pgsql.php b/src/Driver/Pgsql/Pgsql.php index 40b559c..c3fe265 100644 --- a/src/Driver/Pgsql/Pgsql.php +++ b/src/Driver/Pgsql/Pgsql.php @@ -67,7 +67,6 @@ public function setProfiler(ProfilerInterface $profiler): ProfilerAwareInterface return $this; } - #[Override] public function getProfiler(): ?ProfilerInterface { return $this->profiler; diff --git a/src/Driver/Pgsql/PgsqlConfig.php b/src/Driver/Pgsql/PgsqlConfig.php index 8eebaea..b655c87 100644 --- a/src/Driver/Pgsql/PgsqlConfig.php +++ b/src/Driver/Pgsql/PgsqlConfig.php @@ -4,13 +4,24 @@ use PhpDb\Adapter\Exception\InvalidArgumentException; +use function filter_var_array; +use function strtolower; + +use const FILTER_FLAG_EMPTY_STRING_NULL; +use const FILTER_FLAG_STRIP_HIGH; +use const FILTER_FLAG_STRIP_LOW; +use const FILTER_NULL_ON_FAILURE; +use const FILTER_SANITIZE_ENCODED; +use const FILTER_SANITIZE_URL; +use const FILTER_VALIDATE_INT; + class PgsqlConfig { public function __invoke(array $parameters): array { $connectionParameters = []; foreach ($parameters as $name => $value) { - $name = match (strtolower($name)) { + $name = match (strtolower($name)) { 'host', 'hostname' => 'host', 'user', 'username' => 'user', 'password', 'passwd', 'pw' => 'password', @@ -53,4 +64,4 @@ public function __invoke(array $parameters): array return filter_var_array($connectionParameters, $connectionFilters); } -} \ No newline at end of file +} diff --git a/src/Driver/Pgsql/Result.php b/src/Driver/Pgsql/Result.php index c89ec38..92831c6 100644 --- a/src/Driver/Pgsql/Result.php +++ b/src/Driver/Pgsql/Result.php @@ -1,14 +1,14 @@ resource = $resource; $this->count = pg_num_rows($this->resource); @@ -112,42 +109,28 @@ public function rewind() $this->position = 0; } - /** - * Buffer - * - * @return null - */ - public function buffer() + /** todo: track this */ + public function buffer(): void { - return null; } /** * Is buffered - * - * @return false */ - public function isBuffered() + public function isBuffered(): ?bool { return false; } - /** - * Is query result - * - * @return bool - */ - public function isQueryResult() + public function isQueryResult(): bool { return pg_num_fields($this->resource) > 0; } /** * Get affected rows - * - * @return int */ - public function getAffectedRows() + public function getAffectedRows(): int { return pg_affected_rows($this->resource); } @@ -183,10 +166,8 @@ public function count() /** * Get field count - * - * @return int */ - public function getFieldCount() + public function getFieldCount(): int { return pg_num_fields($this->resource); } diff --git a/src/Driver/Pgsql/Statement.php b/src/Driver/Pgsql/Statement.php index 4a1279a..fe480fa 100644 --- a/src/Driver/Pgsql/Statement.php +++ b/src/Driver/Pgsql/Statement.php @@ -6,8 +6,8 @@ use PhpDb\Adapter\Driver\StatementInterface; use PhpDb\Adapter\Exception; use PhpDb\Adapter\ParameterContainer; -use PhpDb\Adapter\Profiler; use PhpDb\Adapter\Pgsql\Connection as PgSqlConnection; +use PhpDb\Adapter\Profiler; use function get_resource_type; use function is_array; @@ -20,16 +20,12 @@ class Statement implements StatementInterface, Profiler\ProfilerAwareInterface { - /** @var int */ protected static int $statementIndex = 0; - /** @var string */ protected string $statementName = ''; - /** @var Pgsql */ protected Pgsql $driver; - /** @var Profiler\ProfilerInterface */ protected Profiler\ProfilerInterface $profiler; /** @var resource */ @@ -38,10 +34,8 @@ class Statement implements StatementInterface, Profiler\ProfilerAwareInterface /** @var resource */ protected $resource; - /** @var string */ protected string $sql; - /** @var ParameterContainer */ protected ParameterContainer $parameterContainer; /** @@ -62,9 +56,6 @@ public function setProfiler(Profiler\ProfilerInterface $profiler): static return $this; } - /** - * @return null|Profiler\ProfilerInterface - */ public function getProfiler(): ?Profiler\ProfilerInterface { return $this->profiler; @@ -74,7 +65,6 @@ public function getProfiler(): ?Profiler\ProfilerInterface * Initialize * * @param resource $pgsql - * @return void * @throws Exception\RuntimeException For invalid or missing postgresql connection. */ public function initialize($pgsql): void @@ -122,8 +112,6 @@ public function setSql($sql): static /** * Get sql - * - * @return string */ public function getSql(): ?string { @@ -143,8 +131,6 @@ public function setParameterContainer(ParameterContainer $parameterContainer): s /** * Get parameter container - * - * @return ParameterContainer */ public function getParameterContainer(): ParameterContainer { @@ -176,8 +162,6 @@ function () use (&$pCount) { /** * Is prepared - * - * @return bool */ public function isPrepared(): bool { @@ -187,11 +171,10 @@ public function isPrepared(): bool /** * Execute * - * @param array|ParameterContainer $parameters * @throws Exception\InvalidQueryException * @return Result */ - public function execute(ParameterContainer|array $parameters = null): ?ResultInterface + public function execute(ParameterContainer|array|null $parameters = null): ?ResultInterface { if (! $this->isPrepared()) { $this->prepare(); diff --git a/src/Platform/Postgresql.php b/src/Platform/Postgresql.php index ffd2efe..7635235 100644 --- a/src/Platform/Postgresql.php +++ b/src/Platform/Postgresql.php @@ -2,15 +2,15 @@ namespace PhpDb\Adapter\Pgsql\Platform; +use PDO; use PhpDb\Adapter\Driver\DriverInterface; use PhpDb\Adapter\Driver\Pgsql; use PhpDb\Adapter\Exception; -use PhpDb\Adapter\Platform\AbstractPlatform; use PhpDb\Adapter\Pgsql\Connection as PgSqlConnection; use PhpDb\Adapter\Pgsql\Driver\Pdo\Pdo as DriverPdo; +use PhpDb\Adapter\Platform\AbstractPlatform; use PhpDb\Sql\Platform\Platform as SqlPlatformDecorator; use PhpDb\Sql\Platform\PlatformDecoratorInterface; -use PDO; use function get_resource_type; use function implode; @@ -37,10 +37,7 @@ class Postgresql extends AbstractPlatform 'pgsql link persistent', ]; - /** - * @param null|Pgsql\Pgsql|DriverPdo|PDO $driver - */ - public function __construct(PDO|Pgsql\Pgsql|DriverPdo $driver = null) + public function __construct(PDO|Pgsql\Pgsql|DriverPdo|null $driver = null) { if ($driver) { $this->setDriver($driver); @@ -100,6 +97,7 @@ public function quoteValue($value): string /** * {@inheritDoc} + * * @param scalar $value * @return string */ @@ -116,7 +114,6 @@ public function quoteTrustedValue($value): string /** * @param string $value - * @return string|null */ protected function quoteViaDriver($value): ?string { diff --git a/test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTrait.php b/test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTrait.php index cb11047..1cd3fa8 100644 --- a/test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTrait.php +++ b/test/integration/Adapter/Driver/Pdo/Postgresql/AdapterTrait.php @@ -1,9 +1,11 @@ markTestSkipped('pdo_pgsql integration tests are not enabled!'); } diff --git a/test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php b/test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php index 0be2c7c..d503372 100644 --- a/test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php +++ b/test/integration/Adapter/Driver/Pdo/Postgresql/TableGatewayTest.php @@ -2,11 +2,11 @@ namespace LaminasIntegrationTest\Db\Adapter\Driver\Pdo\Postgresql; +use LaminasIntegrationTest\Db\Adapter\Driver\Pdo\AdapterTrait as BaseAdapterTrait; use PhpDb\Sql\TableIdentifier; use PhpDb\TableGateway\Feature\FeatureSet; use PhpDb\TableGateway\Feature\SequenceFeature; use PhpDb\TableGateway\TableGateway; -use LaminasIntegrationTest\Db\Adapter\Driver\Pdo\AdapterTrait as BaseAdapterTrait; use PHPUnit\Framework\TestCase; final class TableGatewayTest extends TestCase diff --git a/test/integration/Adapter/Platform/PostgresqlTest.php b/test/integration/Adapter/Platform/PostgresqlTest.php index 60e0718..2083061 100644 --- a/test/integration/Adapter/Platform/PostgresqlTest.php +++ b/test/integration/Adapter/Platform/PostgresqlTest.php @@ -2,11 +2,11 @@ namespace LaminasIntegrationTest\Db\Adapter\Platform; +use Override; use PhpDb\Adapter\Driver\Pdo; -use PhpDb\Adapter\Platform\Postgresql; use PhpDb\Adapter\Pgsql\Connection as PgSqlConnection; use PhpDb\Adapter\Pgsql\Driver\Pgsql; -use Override; +use PhpDb\Adapter\Platform\Postgresql; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; diff --git a/test/unit/Adapter/AdapterServiceFactoryTest.php b/test/unit/Adapter/AdapterServiceFactoryTest.php index 471e101..72b7b92 100644 --- a/test/unit/Adapter/AdapterServiceFactoryTest.php +++ b/test/unit/Adapter/AdapterServiceFactoryTest.php @@ -1,18 +1,19 @@ createServiceManager([ 'db' => [ 'driver' => 'Pdo_Pgsql', - 'database' => ':memory:' - ] + 'database' => ':memory:', + ], ]); $this->factory->__invoke($services, Adapter::class); @@ -69,8 +70,8 @@ public function testV3FactoryReturnsDefaultAdapterWithDefaultProfiler(): void 'db' => [ 'driver' => 'Pdo_Pgsql', 'database' => ':memory:', - 'profiler' => true - ] + 'profiler' => true, + ], ]); $adapter = $this->factory->__invoke($services, Adapter::class); @@ -87,8 +88,8 @@ public function testV3FactoryReturnsDefaultAdapterWithProfilerClassname(): void 'db' => [ 'driver' => 'Pdo_Pgsql', 'database' => ':memory:', - 'profiler' => Profiler::class - ] + 'profiler' => Profiler::class, + ], ]); $adapter = $this->factory->__invoke($services, Adapter::class); @@ -105,8 +106,8 @@ public function testV3FactoryReturnsDefaultAdapterWithProfilerInstance(): void 'db' => [ 'driver' => 'Pdo_Pgsql', 'database' => ':memory:', - 'profiler' => $this->getMockBuilder(ProfilerInterface::class)->getMock() - ] + 'profiler' => $this->getMockBuilder(ProfilerInterface::class)->getMock(), + ], ]); $adapter = $this->factory->__invoke($services, Adapter::class); diff --git a/test/unit/Adapter/AdapterTest.php b/test/unit/Adapter/AdapterTest.php index 57bc7f1..0ee756b 100644 --- a/test/unit/Adapter/AdapterTest.php +++ b/test/unit/Adapter/AdapterTest.php @@ -1,21 +1,23 @@ adapter->setProfiler($profiler = new Profiler\Profiler()); self::assertSame($profiler, $this->adapter->getProfiler()); - $adapter = new Adapter(['driver' => $this->mockDriver, 'profiler' => true], $this->mockPlatform); + $adapter = new Adapter( + $this->mockDriver, + $this->mockPlatform, + $this->getMockBuilder(ResultSetInterface::class)->getMock(), + $profiler + ); self::assertInstanceOf(Profiler\Profiler::class, $adapter->getProfiler()); } - #[TestDox('unit test: Test createDriverFromParameters() will create proper driver type')] - public function testCreateDriver(): void - { - if (extension_loaded('pdo')) { - $adapter = new Adapter(['driver' => 'pdo_sqlite'], $this->mockPlatform); - self::assertInstanceOf(Pdo::class, $adapter->driver); - unset($adapter); - } - } - - #[TestDox('unit test: Test createPlatformFromDriver() will create proper platform from driver')] - public function testCreatePlatform(): void - { - $driver = clone $this->mockDriver; - $driver->expects($this->any())->method('getDatabasePlatformName')->willReturn('Pgsql'); - $adapter = new Adapter($driver); - self::assertInstanceOf(PgsqlPlatform::class, $adapter->platform); - unset($adapter, $driver); - } - #[TestDox('unit test: Test getDriver() will return driver object')] public function testGetDriver(): void { @@ -218,9 +205,9 @@ public function testCreateStatement(): void self::assertSame($this->mockStatement, $this->adapter->createStatement()); } - public function test__get(): void + #[TestDox('unit test: Test __get() magic method')] + public function testMagicGet(): void { - // @codingStandardsIgnoreEnd self::assertSame($this->mockDriver, $this->adapter->driver); /** @psalm-suppress UndefinedMagicPropertyFetch */ self::assertSame($this->mockDriver, $this->adapter->DrivER); @@ -233,8 +220,6 @@ public function test__get(): void $this->adapter->foo; } - // @codingStandardsIgnoreStart - /** * @throws Exception */ @@ -251,11 +236,17 @@ protected function setUp(): void ]) ->getMock(); + $this->mockResultSet = $this->getMockBuilder(ResultSetInterface::class)->getMock(); + $this->mockDriver->method('getDatabasePlatformName')->willReturn('Pgsql'); $this->mockDriver->method('checkEnvironment')->willReturn(true); $this->mockDriver->method('getConnection')->willReturn($this->mockConnection); - $this->mockDriver->method('createStatement')->willReturn($this->mockStatement); + //$this->mockDriver->method('createStatement')->willReturn($this->mockStatement); - $this->adapter = new Adapter($this->mockDriver, $this->mockPlatform); + $this->adapter = new Adapter( + $this->mockDriver, + $this->mockPlatform, + $this->mockResultSet + ); } } diff --git a/test/unit/Adapter/ConfigProviderTest.php b/test/unit/Adapter/ConfigProviderTest.php index 74fc5ab..59a61ca 100644 --- a/test/unit/Adapter/ConfigProviderTest.php +++ b/test/unit/Adapter/ConfigProviderTest.php @@ -1,17 +1,19 @@ > */ private array $config = [ 'aliases' => [ - PlatformInterface::class => Platform\Pgsql::class, + PlatformInterface::class => Platform\Postgresql::class, ProfilerInterface::class => Profiler::class, ], 'factories' => [ - AdapterInterface::class => AdapterServiceFactory::class, - DriverInterface::class => Driver\Pdo\DriverFactory::class, - Platform\Pgsql::class => InvokableFactory::class, - Profiler::class => InvokableFactory::class, + AdapterInterface::class => AdapterServiceFactory::class, + DriverInterface::class => Driver\Pdo\DriverFactory::class, + Platform\Postgresql::class => InvokableFactory::class, + Profiler::class => InvokableFactory::class, ], ]; diff --git a/test/unit/Adapter/ModuleTest.php b/test/unit/Adapter/ModuleTest.php deleted file mode 100644 index 954fa5b..0000000 --- a/test/unit/Adapter/ModuleTest.php +++ /dev/null @@ -1,42 +0,0 @@ -> */ - private array $config = [ - 'aliases' => [ - PlatformInterface::class => Platform\Pgsql::class, - ProfilerInterface::class => Profiler::class, - ], - 'factories' => [ - AdapterInterface::class => AdapterServiceFactory::class, - DriverInterface::class => Driver\Pdo\DriverFactory::class, - Platform\Pgsql::class => InvokableFactory::class, - Profiler::class => InvokableFactory::class, - ], - ]; - - public function testProvidesExpectedConfiguration(): Module - { - $provider = new Module(); - self::assertEquals(['service_manager' => $this->config], $provider->getConfig()); - - return $provider; - } -} From d43adc006c4a5edd85d01251cdcd813d89d84e9f Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Wed, 1 Oct 2025 00:17:38 -0500 Subject: [PATCH 7/9] Fix namespacing in unit/integration test Add FixtureLoader for integration test Add Various Container\* factory and factoryfactory class stubs Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- ...actory.php => AdapterInterfaceFactory.php} | 2 +- src/Container/AdapterManagerDelegator.php | 10 ++++++++ .../ConnectionInterfaceFactoryFactory.php | 10 ++++++++ .../DriverInterfaceFactoryFactory.php | 10 ++++++++ .../PdoConnectionInterfaceFactory.php | 10 ++++++++ src/Container/PdoResultFactory.php | 10 ++++++++ src/Container/PdoStatementFactory.php | 10 ++++++++ src/Container/PlatformInterfaceFactory.php | 10 ++++++++ .../PlatformInterfaceFactoryFactory.php | 10 ++++++++ src/Driver/Pgsql/PgsqlConfig.php | 2 ++ src/Driver/Pgsql/Statement.php | 2 ++ src/Platform/Postgresql.php | 4 +++- .../Driver/Pdo/Postgresql/AdapterTest.php | 6 ++--- .../Pdo/Postgresql/TableGatewayTest.php | 4 ++-- .../Adapter/Platform/PostgresqlTest.php | 2 +- .../FixtureLoader/FixtureLoaderInterface.php | 12 ++++++++++ .../PgsqlFixtureLoader.php | 24 ++++++++++--------- ...st.php => AdapterInterfaceFactoryTest.php} | 12 +++++----- test/unit/Adapter/ConfigProviderTest.php | 2 +- 19 files changed, 126 insertions(+), 26 deletions(-) rename src/Container/{AdapterServiceFactory.php => AdapterInterfaceFactory.php} (95%) create mode 100644 src/Container/AdapterManagerDelegator.php create mode 100644 src/Container/ConnectionInterfaceFactoryFactory.php create mode 100644 src/Container/DriverInterfaceFactoryFactory.php create mode 100644 src/Container/PdoConnectionInterfaceFactory.php create mode 100644 src/Container/PdoResultFactory.php create mode 100644 src/Container/PdoStatementFactory.php create mode 100644 src/Container/PlatformInterfaceFactory.php create mode 100644 src/Container/PlatformInterfaceFactoryFactory.php create mode 100644 test/integration/FixtureLoader/FixtureLoaderInterface.php rename test/integration/{Platform => FixtureLoader}/PgsqlFixtureLoader.php (73%) rename test/unit/Adapter/{AdapterServiceFactoryTest.php => AdapterInterfaceFactoryTest.php} (91%) diff --git a/src/Container/AdapterServiceFactory.php b/src/Container/AdapterInterfaceFactory.php similarity index 95% rename from src/Container/AdapterServiceFactory.php rename to src/Container/AdapterInterfaceFactory.php index e22113d..0814e11 100644 --- a/src/Container/AdapterServiceFactory.php +++ b/src/Container/AdapterInterfaceFactory.php @@ -14,7 +14,7 @@ use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; -class AdapterServiceFactory implements FactoryInterface +class AdapterInterfaceFactory implements FactoryInterface { /** * Create db adapter service diff --git a/src/Container/AdapterManagerDelegator.php b/src/Container/AdapterManagerDelegator.php new file mode 100644 index 0000000..742a6ae --- /dev/null +++ b/src/Container/AdapterManagerDelegator.php @@ -0,0 +1,10 @@ +pdo->exec(sprintf( "CREATE DATABASE %s", - getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE') + getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_DATABASE') )) ) { throw new Exception(sprintf( "I cannot create the PostgreSQL %s test database: %s", - getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE'), + getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_DATABASE'), print_r($this->pdo->errorInfo(), true) )); } @@ -50,7 +52,7 @@ public function createDatabase(): void if (false === $this->pdo->exec(file_get_contents($this->fixtureFile))) { throw new Exception(sprintf( "I cannot create the table for %s database. Check the %s file. %s ", - getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE'), + getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_DATABASE'), $this->fixtureFile, print_r($this->pdo->errorInfo(), true) )); @@ -73,7 +75,7 @@ public function dropDatabase(): void $this->pdo->exec(sprintf( "DROP DATABASE IF EXISTS %s", - getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE') + getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_DATABASE') )); $this->disconnect(); @@ -84,16 +86,16 @@ public function dropDatabase(): void */ protected function connect(bool $useDb = false): void { - $dsn = 'pgsql:host=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME'); + $dsn = 'pgsql:host=' . getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_HOSTNAME'); if ($useDb) { - $dsn .= ';dbname=' . getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_DATABASE'); + $dsn .= ';dbname=' . getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_DATABASE'); } $this->pdo = new PDO( $dsn, - getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_USERNAME'), - getenv('TESTS_LAMINAS_DB_ADAPTER_DRIVER_PGSQL_PASSWORD') + getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_USERNAME'), + getenv('TESTS_PHPDB_ADAPTER_DRIVER_PGSQL_PASSWORD') ); } diff --git a/test/unit/Adapter/AdapterServiceFactoryTest.php b/test/unit/Adapter/AdapterInterfaceFactoryTest.php similarity index 91% rename from test/unit/Adapter/AdapterServiceFactoryTest.php rename to test/unit/Adapter/AdapterInterfaceFactoryTest.php index 72b7b92..309cd68 100644 --- a/test/unit/Adapter/AdapterServiceFactoryTest.php +++ b/test/unit/Adapter/AdapterInterfaceFactoryTest.php @@ -2,14 +2,14 @@ declare(strict_types=1); -namespace LaminasTest\Db\Pgsql; +namespace PhpDbTest\Pgsql; use Laminas\ServiceManager\ServiceLocatorInterface; use Laminas\ServiceManager\ServiceManager; use Override; use PhpDb\Adapter\Adapter; use PhpDb\Adapter\Pgsql\ConfigProvider; -use PhpDb\Adapter\Pgsql\Container\AdapterServiceFactory; +use PhpDb\Adapter\Pgsql\Container\AdapterInterfaceFactory; use PhpDb\Adapter\Profiler\Profiler; use PhpDb\Adapter\Profiler\ProfilerInterface; use PHPUnit\Framework\Attributes\CoversMethod; @@ -19,10 +19,10 @@ use function extension_loaded; -#[CoversMethod(AdapterServiceFactory::class, '__invoke')] -final class AdapterServiceFactoryTest extends TestCase +#[CoversMethod(AdapterInterfaceFactory::class, '__invoke')] +final class AdapterInterfaceFactoryTest extends TestCase { - private AdapterServiceFactory $factory; + private AdapterInterfaceFactory $factory; protected function createServiceManager(array $dbConfig): ServiceLocatorInterface { @@ -39,7 +39,7 @@ protected function setUp(): void $this->markTestSkipped('Adapter factory tests require pdo_sqlite'); } - $this->factory = new AdapterServiceFactory(); + $this->factory = new AdapterInterfaceFactory(); } /** diff --git a/test/unit/Adapter/ConfigProviderTest.php b/test/unit/Adapter/ConfigProviderTest.php index 59a61ca..4132144 100644 --- a/test/unit/Adapter/ConfigProviderTest.php +++ b/test/unit/Adapter/ConfigProviderTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace LaminasTest\Db\Pgsql; +namespace PhpDbTest\Pgsql; use Laminas\ServiceManager\Factory\InvokableFactory; use PhpDb\Adapter\AdapterInterface; From ff207ab15d0eb64c97cb1609e03caa750b8945a9 Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Tue, 7 Oct 2025 04:19:18 -0500 Subject: [PATCH 8/9] latest revisions bump deps enable phpunit runs (has failures/errors) Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- composer.json | 2 +- composer.lock | 37 +-- phpunit.xml.dist | 20 +- src/Container/AdapterInterfaceFactory.php | 20 +- src/Metadata/Source/PostgresqlMetadata.php | 363 +++++++++++++++++++++ src/Platform/Postgresql.php | 54 +-- 6 files changed, 414 insertions(+), 82 deletions(-) create mode 100644 src/Metadata/Source/PostgresqlMetadata.php diff --git a/composer.json b/composer.json index 740a95e..e5f63c3 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ }, "require": { "php": "~8.2.0 || ~8.3.0 || ~8.4.0", - "php-db/phpdb": "^0.1.0" + "php-db/phpdb": "^0.2.1" }, "require-dev": { "laminas/laminas-coding-standard": "^3.0.1", diff --git a/composer.lock b/composer.lock index 992d1a4..0413512 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4a3049b922cefbc90e1f498dd0fdca74", + "content-hash": "93b90a40dd4fe8c39502da74c4585c56", "packages": [ { "name": "brick/varexporter", @@ -259,22 +259,22 @@ }, { "name": "php-db/phpdb", - "version": "0.1.1", + "version": "0.2.1", "source": { "type": "git", "url": "https://github.com/php-db/phpdb.git", - "reference": "f671eabd951cd5da927ea814c8d0f83bb16247e0" + "reference": "d221b024cb3aea77992f41a962913918301dc92e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-db/phpdb/zipball/f671eabd951cd5da927ea814c8d0f83bb16247e0", - "reference": "f671eabd951cd5da927ea814c8d0f83bb16247e0", + "url": "https://api.github.com/repos/php-db/phpdb/zipball/d221b024cb3aea77992f41a962913918301dc92e", + "reference": "d221b024cb3aea77992f41a962913918301dc92e", "shasum": "" }, "require": { "laminas/laminas-servicemanager": "^4.0.0", "laminas/laminas-stdlib": "^3.20.0", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0" }, "conflict": { "laminas/laminas-db": "*", @@ -283,10 +283,10 @@ "require-dev": { "laminas/laminas-coding-standard": "^3.0.1", "laminas/laminas-eventmanager": "^3.14.0", - "phpunit/phpunit": "^11.5.12", - "psalm/plugin-phpunit": "^0.19.2", - "rector/rector": "^2.0", - "vimeo/psalm": "^6.8.8" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^11.5.15", + "rector/rector": "^2.0" }, "suggest": { "laminas/laminas-eventmanager": "Laminas\\EventManager component", @@ -295,7 +295,7 @@ "type": "library", "extra": { "laminas": { - "config-provider": "PhpDb\\Container\\ConfigProvider" + "config-provider": "PhpDb\\ConfigProvider" } }, "autoload": { @@ -321,7 +321,7 @@ "issues": "https://github.com/php-db/phpdb/issues", "source": "https://github.com/php-db/phpdb" }, - "time": "2025-09-15T22:14:40+00:00" + "time": "2025-10-07T08:36:48+00:00" }, { "name": "psr/container", @@ -754,16 +754,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.29", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan-phar-composer-source.git", - "reference": "git" - }, + "version": "2.1.30", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d618573eed4a1b6b75e37b2e0b65ac65c885d88e", - "reference": "d618573eed4a1b6b75e37b2e0b65ac65c885d88e", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a4a7f159927983dd4f7c8020ed227d80b7f39d7d", + "reference": "a4a7f159927983dd4f7c8020ed227d80b7f39d7d", "shasum": "" }, "require": { @@ -808,7 +803,7 @@ "type": "github" } ], - "time": "2025-09-25T06:58:18+00:00" + "time": "2025-10-02T16:07:52+00:00" }, { "name": "phpstan/phpstan-phpunit", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d974467..d3efe8b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -14,24 +14,18 @@ failOnDeprecation="true" failOnWarning="true"> - - test/unit + + ./test/unit - + - - - src + ./src - - test/config - test/resource - \ No newline at end of file diff --git a/src/Container/AdapterInterfaceFactory.php b/src/Container/AdapterInterfaceFactory.php index 0814e11..602df73 100644 --- a/src/Container/AdapterInterfaceFactory.php +++ b/src/Container/AdapterInterfaceFactory.php @@ -4,17 +4,21 @@ namespace PhpDb\Adapter\Pgsql\Container; -use Laminas\ServiceManager\Factory\FactoryInterface; +use Laminas\ServiceManager\Exception\ServiceNotFoundException; use PhpDb\Adapter\Adapter; +use PhpDb\Adapter\AdapterInterface; use PhpDb\Adapter\Driver\DriverInterface; -use PhpDb\Adapter\Pgsql\Platform; +use PhpDb\Adapter\Driver\PdoDriverInterface; +use PhpDb\Adapter\Exception\RuntimeException; +use PhpDb\Adapter\Platform\PlatformInterface; use PhpDb\Adapter\Profiler\ProfilerInterface; +use PhpDb\Container\AdapterManager; use PhpDb\ResultSet\ResultSetInterface; -use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; -use Psr\Container\NotFoundExceptionInterface; -class AdapterInterfaceFactory implements FactoryInterface +use function sprintf; + +class AdapterInterfaceFactory { /** * Create db adapter service @@ -23,11 +27,7 @@ class AdapterInterfaceFactory implements FactoryInterface * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function __invoke( - ContainerInterface $container, - string $requestedName, - ?array $options = null - ): Adapter { + public function __invoke(ContainerInterface $container): AdapterInterface { $resultSetPrototype = $container->has(ResultSetInterface::class) ? $container->get(ResultSetInterface::class) : null; diff --git a/src/Metadata/Source/PostgresqlMetadata.php b/src/Metadata/Source/PostgresqlMetadata.php new file mode 100644 index 0000000..45c4e3d --- /dev/null +++ b/src/Metadata/Source/PostgresqlMetadata.php @@ -0,0 +1,363 @@ +data['schemas'])) { + return; + } + $this->prepareDataHierarchy('schemas'); + + $p = $this->adapter->getPlatform(); + + $sql = 'SELECT ' . $p->quoteIdentifier('schema_name') + . ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'schemata']) + . ' WHERE ' . $p->quoteIdentifier('schema_name') + . ' != \'information_schema\'' + . ' AND ' . $p->quoteIdentifier('schema_name') . " NOT LIKE 'pg_%'"; + + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); + + $schemas = []; + foreach ($results->toArray() as $row) { + $schemas[] = $row['schema_name']; + } + + $this->data['schemas'] = $schemas; + } + + #[Override] + protected function loadTableNameData(string $schema): void + { + if (isset($this->data['table_names'][$schema])) { + return; + } + $this->prepareDataHierarchy('table_names', $schema); + + $p = $this->adapter->getPlatform(); + + $isColumns = [ + ['t', 'table_name'], + ['t', 'table_type'], + ['v', 'view_definition'], + ['v', 'check_option'], + ['v', 'is_updatable'], + ]; + + array_walk($isColumns, function (&$c) use ($p) { + $c = $p->quoteIdentifierChain($c); + }); + + $sql = 'SELECT ' . implode(', ', $isColumns) + . ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'tables']) . ' t' + + . ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'views']) . ' v' + . ' ON ' . $p->quoteIdentifierChain(['t', 'table_schema']) + . ' = ' . $p->quoteIdentifierChain(['v', 'table_schema']) + . ' AND ' . $p->quoteIdentifierChain(['t', 'table_name']) + . ' = ' . $p->quoteIdentifierChain(['v', 'table_name']) + + . ' WHERE ' . $p->quoteIdentifierChain(['t', 'table_type']) + . ' IN (\'BASE TABLE\', \'VIEW\')'; + + if ($schema !== self::DEFAULT_SCHEMA) { + $sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema']) + . ' = ' . $p->quoteTrustedValue($schema); + } else { + $sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema']) + . ' != \'information_schema\''; + } + + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); + + $tables = []; + foreach ($results->toArray() as $row) { + $tables[$row['table_name']] = [ + 'table_type' => $row['table_type'], + 'view_definition' => $row['view_definition'], + 'check_option' => $row['check_option'], + 'is_updatable' => 'YES' === $row['is_updatable'], + ]; + } + + $this->data['table_names'][$schema] = $tables; + } + + #[Override] + protected function loadColumnData(string $table, string $schema): void + { + if (isset($this->data['columns'][$schema][$table])) { + return; + } + + $this->prepareDataHierarchy('columns', $schema, $table); + + $platform = $this->adapter->getPlatform(); + + $isColumns = [ + 'table_name', + 'column_name', + 'ordinal_position', + 'column_default', + 'is_nullable', + 'data_type', + 'character_maximum_length', + 'character_octet_length', + 'numeric_precision', + 'numeric_scale', + ]; + + array_walk($isColumns, function (&$c) use ($platform) { + $c = $platform->quoteIdentifier($c); + }); + + $sql = 'SELECT ' . implode(', ', $isColumns) + . ' FROM ' . $platform->quoteIdentifier('information_schema') + . $platform->getIdentifierSeparator() . $platform->quoteIdentifier('columns') + . ' WHERE ' . $platform->quoteIdentifier('table_schema') + . ' != \'information\'' + . ' AND ' . $platform->quoteIdentifier('table_name') + . ' = ' . $platform->quoteTrustedValue($table); + + if ($schema !== '__DEFAULT_SCHEMA__') { + $sql .= ' AND ' . $platform->quoteIdentifier('table_schema') + . ' = ' . $platform->quoteTrustedValue($schema); + } + + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); + $columns = []; + foreach ($results->toArray() as $row) { + $columns[$row['column_name']] = [ + 'ordinal_position' => $row['ordinal_position'], + 'column_default' => $row['column_default'], + 'is_nullable' => 'YES' === $row['is_nullable'], + 'data_type' => $row['data_type'], + 'character_maximum_length' => $row['character_maximum_length'], + 'character_octet_length' => $row['character_octet_length'], + 'numeric_precision' => $row['numeric_precision'], + 'numeric_scale' => $row['numeric_scale'], + 'numeric_unsigned' => null, + 'erratas' => [], + ]; + } + + $this->data['columns'][$schema][$table] = $columns; + } + + #[Override] + protected function loadConstraintData(string $table, string $schema): void + { + // phpcs:disable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps + if (isset($this->data['constraints'][$schema][$table])) { + return; + } + + $this->prepareDataHierarchy('constraints', $schema, $table); + + $isColumns = [ + ['t', 'table_name'], + ['tc', 'constraint_name'], + ['tc', 'constraint_type'], + ['kcu', 'column_name'], + ['cc', 'check_clause'], + ['rc', 'match_option'], + ['rc', 'update_rule'], + ['rc', 'delete_rule'], + ['referenced_table_schema' => 'kcu2', 'table_schema'], + ['referenced_table_name' => 'kcu2', 'table_name'], + ['referenced_column_name' => 'kcu2', 'column_name'], + ]; + + $p = $this->adapter->getPlatform(); + + array_walk($isColumns, function (&$c) use ($p) { + $alias = key($c); + $c = $p->quoteIdentifierChain($c); + if (is_string($alias)) { + $c .= ' ' . $p->quoteIdentifier($alias); + } + }); + + $sql = 'SELECT ' . implode(', ', $isColumns) + . ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'tables']) . ' t' + + . ' INNER JOIN ' . $p->quoteIdentifierChain(['information_schema', 'table_constraints']) . ' tc' + . ' ON ' . $p->quoteIdentifierChain(['t', 'table_schema']) + . ' = ' . $p->quoteIdentifierChain(['tc', 'table_schema']) + . ' AND ' . $p->quoteIdentifierChain(['t', 'table_name']) + . ' = ' . $p->quoteIdentifierChain(['tc', 'table_name']) + + . ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'key_column_usage']) . ' kcu' + . ' ON ' . $p->quoteIdentifierChain(['tc', 'table_schema']) + . ' = ' . $p->quoteIdentifierChain(['kcu', 'table_schema']) + . ' AND ' . $p->quoteIdentifierChain(['tc', 'table_name']) + . ' = ' . $p->quoteIdentifierChain(['kcu', 'table_name']) + . ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name']) + . ' = ' . $p->quoteIdentifierChain(['kcu', 'constraint_name']) + + . ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'check_constraints']) . ' cc' + . ' ON ' . $p->quoteIdentifierChain(['tc', 'constraint_schema']) + . ' = ' . $p->quoteIdentifierChain(['cc', 'constraint_schema']) + . ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name']) + . ' = ' . $p->quoteIdentifierChain(['cc', 'constraint_name']) + + . ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'referential_constraints']) . ' rc' + . ' ON ' . $p->quoteIdentifierChain(['tc', 'constraint_schema']) + . ' = ' . $p->quoteIdentifierChain(['rc', 'constraint_schema']) + . ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name']) + . ' = ' . $p->quoteIdentifierChain(['rc', 'constraint_name']) + + . ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'key_column_usage']) . ' kcu2' + . ' ON ' . $p->quoteIdentifierChain(['rc', 'unique_constraint_schema']) + . ' = ' . $p->quoteIdentifierChain(['kcu2', 'constraint_schema']) + . ' AND ' . $p->quoteIdentifierChain(['rc', 'unique_constraint_name']) + . ' = ' . $p->quoteIdentifierChain(['kcu2', 'constraint_name']) + . ' AND ' . $p->quoteIdentifierChain(['kcu', 'position_in_unique_constraint']) + . ' = ' . $p->quoteIdentifierChain(['kcu2', 'ordinal_position']) + + . ' WHERE ' . $p->quoteIdentifierChain(['t', 'table_name']) + . ' = ' . $p->quoteTrustedValue($table) + . ' AND ' . $p->quoteIdentifierChain(['t', 'table_type']) + . ' IN (\'BASE TABLE\', \'VIEW\')'; + + if ($schema !== self::DEFAULT_SCHEMA) { + $sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema']) + . ' = ' . $p->quoteTrustedValue($schema); + } else { + $sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema']) + . ' != \'information_schema\''; + } + + $sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(['tc', 'constraint_type']) + . " WHEN 'PRIMARY KEY' THEN 1" + . " WHEN 'UNIQUE' THEN 2" + . " WHEN 'FOREIGN KEY' THEN 3" + . " WHEN 'CHECK' THEN 4" + . " ELSE 5 END" + . ', ' . $p->quoteIdentifierChain(['tc', 'constraint_name']) + . ', ' . $p->quoteIdentifierChain(['kcu', 'ordinal_position']); + + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); + + $name = null; + $constraints = []; + foreach ($results->toArray() as $row) { + if ($row['constraint_name'] !== $name) { + $name = $row['constraint_name']; + $constraints[$name] = [ + 'constraint_name' => $name, + 'constraint_type' => $row['constraint_type'], + 'table_name' => $row['table_name'], + ]; + if ('CHECK' === $row['constraint_type']) { + $constraints[$name]['check_clause'] = $row['check_clause']; + continue; + } + $constraints[$name]['columns'] = []; + $isFK = 'FOREIGN KEY' === $row['constraint_type']; + if ($isFK) { + $constraints[$name]['referenced_table_schema'] = $row['referenced_table_schema']; + $constraints[$name]['referenced_table_name'] = $row['referenced_table_name']; + $constraints[$name]['referenced_columns'] = []; + $constraints[$name]['match_option'] = $row['match_option']; + $constraints[$name]['update_rule'] = $row['update_rule']; + $constraints[$name]['delete_rule'] = $row['delete_rule']; + } + } + $constraints[$name]['columns'][] = $row['column_name']; + if ($isFK) { + $constraints[$name]['referenced_columns'][] = $row['referenced_column_name']; + } + } + + $this->data['constraints'][$schema][$table] = $constraints; + // phpcs:enable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps + } + + #[Override] + protected function loadTriggerData(string $schema): void + { + if (isset($this->data['triggers'][$schema])) { + return; + } + + $this->prepareDataHierarchy('triggers', $schema); + + $p = $this->adapter->getPlatform(); + + $isColumns = [ + 'trigger_name', + 'event_manipulation', + 'event_object_catalog', + 'event_object_schema', + 'event_object_table', + 'action_order', + 'action_condition', + 'action_statement', + 'action_orientation', + ['action_timing' => 'condition_timing'], + ['action_reference_old_table' => 'condition_reference_old_table'], + ['action_reference_new_table' => 'condition_reference_new_table'], + 'created', + ]; + + array_walk($isColumns, function (&$c) use ($p) { + if (is_array($c)) { + $alias = key($c); + $c = $p->quoteIdentifierChain($c); + if (is_string($alias)) { + $c .= ' ' . $p->quoteIdentifier($alias); + } + } else { + $c = $p->quoteIdentifier($c); + } + }); + + $sql = 'SELECT ' . implode(', ', $isColumns) + . ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'triggers']) + . ' WHERE '; + + if ($schema !== self::DEFAULT_SCHEMA) { + $sql .= $p->quoteIdentifier('trigger_schema') + . ' = ' . $p->quoteTrustedValue($schema); + } else { + $sql .= $p->quoteIdentifier('trigger_schema') + . ' != \'information_schema\''; + } + + $results = $this->adapter->query($sql, AdapterInterface::QUERY_MODE_EXECUTE); + + $data = []; + foreach ($results->toArray() as $row) { + $row = array_change_key_case($row, CASE_LOWER); + $row['action_reference_old_row'] = 'OLD'; + $row['action_reference_new_row'] = 'NEW'; + if (null !== $row['created']) { + $row['created'] = new DateTime($row['created']); + } + $data[$row['trigger_name']] = $row; + } + + $this->data['triggers'][$schema] = $data; + } +} diff --git a/src/Platform/Postgresql.php b/src/Platform/Postgresql.php index 0be14db..55fac46 100644 --- a/src/Platform/Postgresql.php +++ b/src/Platform/Postgresql.php @@ -4,12 +4,15 @@ namespace PhpDb\Adapter\Pgsql\Platform; +use Override; use PDO; use PgSql\Connection as PgSqlConnection; +use PhpDb\Adapter\AdapterInterface; use PhpDb\Adapter\Driver\DriverInterface; -use PhpDb\Adapter\Driver\Pgsql; +use PhpDb\Adapter\Driver\PdoDriverInterface; +use PhpDb\Adapter\Driver\Pgsql\Pgsql; use PhpDb\Adapter\Exception; -use PhpDb\Adapter\Pgsql\Driver\Pdo\Pdo as DriverPdo; +use PhpDb\Adapter\Pgsql\Driver\Pdo\Pdo as PdoDriver; use PhpDb\Adapter\Platform\AbstractPlatform; use PhpDb\Sql\Platform\Platform as SqlPlatformDecorator; use PhpDb\Sql\Platform\PlatformDecoratorInterface; @@ -23,6 +26,7 @@ class Postgresql extends AbstractPlatform { + public final const PLATFORM_NAME = 'PostgreSQL'; /** * Overrides value from AbstractPlatform to use proper escaping for Postgres * @@ -30,58 +34,31 @@ class Postgresql extends AbstractPlatform */ protected $quoteIdentifierTo = '""'; - /** @var null|resource|PDO|DriverPdo|Pgsql\Pgsql */ - protected $driver; - /** @var string[] */ private $knownPgsqlResources = [ 'pgsql link', 'pgsql link persistent', ]; - public function __construct(PDO|Pgsql\Pgsql|DriverPdo|null $driver = null) - { - if ($driver) { - $this->setDriver($driver); - } - } - - /** - * @param Pgsql\Pgsql|DriverPdo|resource|PDO $driver - * @throws Exception\InvalidArgumentException - * @return $this Provides a fluent interface - */ - public function setDriver($driver): static - { - if ( - $driver instanceof Pgsql\Pgsql - || ($driver instanceof DriverPdo && $driver->getDatabasePlatformName() === 'Postgresql') - || $driver instanceof PgSqlConnection // PHP 8.1+ - || (is_resource($driver) && in_array(get_resource_type($driver), $this->knownPgsqlResources, true)) - || ($driver instanceof PDO && $driver->getAttribute(PDO::ATTR_DRIVER_NAME) === 'pgsql') - ) { - $this->driver = $driver; - - return $this; - } - - throw new Exception\InvalidArgumentException( - '$driver must be a Pgsql or Postgresql PDO PhpDb\Adapter\Driver, pgsql link resource' - . ' or Postgresql PDO instance' - ); + public function __construct( + //private readonly PDO|Pgsql|PdoDriver $driver + private readonly DriverInterface|PdoDriverInterface|PDO $driver, + ) { } /** * {@inheritDoc} */ + #[Override] public function getName(): string { - return 'PostgreSQL'; + return self::PLATFORM_NAME; } /** * {@inheritDoc} */ + #[Override] public function quoteIdentifierChain($identifierChain): string { return '"' . implode('"."', (array) str_replace('"', '""', $identifierChain)) . '"'; @@ -90,6 +67,7 @@ public function quoteIdentifierChain($identifierChain): string /** * {@inheritDoc} */ + #[Override] public function quoteValue($value): string { $quotedViaDriverValue = $this->quoteViaDriver($value); @@ -103,6 +81,7 @@ public function quoteValue($value): string * @param scalar $value * @return string */ + #[Override] public function quoteTrustedValue($value): string { $quotedViaDriverValue = $this->quoteViaDriver($value); @@ -134,8 +113,9 @@ protected function quoteViaDriver($value): ?string return null; } + #[Override] public function getSqlPlatformDecorator(): PlatformDecoratorInterface { - return new SqlPlatformDecorator($this->driver); + return new SqlPlatformDecorator($this); } } From de10ad15176bbe8135939c4961e8b92e266f71ad Mon Sep 17 00:00:00 2001 From: Joey Smith Date: Tue, 7 Oct 2025 21:04:24 -0500 Subject: [PATCH 9/9] testing ci action config Signed-off-by: Joey Smith Signed-off-by: Joey Smith --- .github/workflows/continuous-integration.yml | 16 +++++++--------- phpunit.xml.dist | 7 +++++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 7ed76f2..289e5ff 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -30,18 +30,16 @@ jobs: with: job: ${{ matrix.job }} services: - mysql: - image: mysql:5.7 + postgres: + image: postgres env: - MYSQL_ROOT_PASSWORD: 'password' - MYSQL_ROOT_HOST: '%' - MYSQL_USER: 'gha' - MYSQL_PASSWORD: 'password' - MYSQL_DATABASE: 'laminasdb_test' + POSTGRES_USER: 'gha' + POSTGRES_PASSWORD: 'password' + POSTGRES_DB: 'phpdb_test' options: >- - --health-cmd="mysqladmin ping" + --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 3 ports: - - 3306 \ No newline at end of file + - 5432 \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d3efe8b..97ae618 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -28,4 +28,11 @@ ./src + + + + + + + \ No newline at end of file