diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..03ed54b6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,24 @@ +# +# JBZoo Toolbox - Csv-Blueprint. +# +# This file is part of the JBZoo Toolbox project. +# For the full copyright and license information, please view the LICENSE +# file that was distributed with this source code. +# +# @license MIT +# @copyright Copyright (C) JBZoo.com, All rights reserved. +# @see https://github.com/JBZoo/Csv-Blueprint +# + +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..0e97e3d1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,33 @@ +# +# JBZoo Toolbox - Csv-Blueprint. +# +# This file is part of the JBZoo Toolbox project. +# For the full copyright and license information, please view the LICENSE +# file that was distributed with this source code. +# +# @license MIT +# @copyright Copyright (C) JBZoo.com, All rights reserved. +# @see https://github.com/JBZoo/Csv-Blueprint +# + +/.github export-ignore +/build export-ignore +/tests export-ignore +/.editorconfig export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.phan.php export-ignore +/.travis.yml export-ignore +/composer.lock export-ignore +/phpunit.xml.dist export-ignore +/Makefile export-ignore + +* text eol=lf + +# (binary is a macro for -text -diff) +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.ttf binary diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml new file mode 100644 index 00000000..5c2e204a --- /dev/null +++ b/.github/workflows/demo.yml @@ -0,0 +1,68 @@ +# +# JBZoo Toolbox - Csv-Blueprint. +# +# This file is part of the JBZoo Toolbox project. +# For the full copyright and license information, please view the LICENSE +# file that was distributed with this source code. +# +# @license MIT +# @copyright Copyright (C) JBZoo.com, All rights reserved. +# @see https://github.com/JBZoo/Csv-Blueprint +# + +name: Demo + +on: + pull_request: + branches: + - "*" + push: + branches: + - 'master' + +env: + COLUMNS: 120 + TERM_PROGRAM: Hyper + +jobs: + pure-php: + name: Pure PHP + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.3 + tools: composer + + - name: Build the Project + run: make update + + - name: Validate CSV (default is table) + run: make demo-github + continue-on-error: true + + - name: Validate CSV (text) + run: OUTPUT=text make demo-github + continue-on-error: true + + - name: Validate CSV (github) + run: OUTPUT=github make demo-github + continue-on-error: true + + - name: Validate CSV (gitlab) + run: OUTPUT=gitlab make demo-github + continue-on-error: true + + - name: Validate CSV (teamcity) + run: OUTPUT=teamcity make demo-github + continue-on-error: true + + - name: Validate CSV (junit) + run: OUTPUT=junit make demo-github + continue-on-error: true diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..5cf213ea --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,140 @@ +# +# JBZoo Toolbox - Csv-Blueprint. +# +# This file is part of the JBZoo Toolbox project. +# For the full copyright and license information, please view the LICENSE +# file that was distributed with this source code. +# +# @license MIT +# @copyright Copyright (C) JBZoo.com, All rights reserved. +# @see https://github.com/JBZoo/Csv-Blueprint +# + +name: CI + +on: + pull_request: + branches: + - "*" + push: + branches: + - 'master' + schedule: + - cron: '12 */8 * * *' + +env: + COLUMNS: 120 + TERM_PROGRAM: Hyper + +jobs: + phpunit: + name: PHPUnit + runs-on: ubuntu-latest + env: + JBZOO_COMPOSER_UPDATE_FLAGS: ${{ matrix.composer_flags }} + strategy: + matrix: + php-version: [ 8.1, 8.2, 8.3 ] + coverage: [ xdebug, none ] + composer_flags: [ "--prefer-lowest", "" ] + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: ${{ matrix.coverage }} + tools: composer + extensions: ast + + - name: Build the Project + run: make update --no-print-directory + + - name: 🧪 PHPUnit Tests + run: make test --no-print-directory + + - name: Uploading coverage to coveralls + if: ${{ matrix.coverage == 'xdebug' }} + continue-on-error: true + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: make report-coveralls --no-print-directory || true + + - name: Upload Artifacts + uses: actions/upload-artifact@v3 + continue-on-error: true + with: + name: PHPUnit - ${{ matrix.php-version }} - ${{ matrix.coverage }} + path: build/ + + + linters: + name: Linters + runs-on: ubuntu-latest + strategy: + matrix: + php-version: [ 8.1, 8.2, 8.3 ] + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: none + tools: composer + extensions: ast + + - name: Build the Project + run: make update --no-print-directory + + - name: 👍 Code Quality + run: make codestyle --no-print-directory + + - name: Upload Artifacts + uses: actions/upload-artifact@v3 + continue-on-error: true + with: + name: Linters - ${{ matrix.php-version }} + path: build/ + + + report: + name: Reports + runs-on: ubuntu-latest + strategy: + matrix: + php-version: [ 8.1, 8.2, 8.3 ] + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: xdebug + tools: composer + extensions: ast + + - name: Build the Project + run: make update --no-print-directory + + - name: 📝 Build Reports + run: make report-all --no-print-directory + + - name: Upload Artifacts + uses: actions/upload-artifact@v3 + continue-on-error: true + with: + name: Reports - ${{ matrix.php-version }} + path: build/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b0f75c93 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# +# JBZoo Toolbox - Csv-Blueprint. +# +# This file is part of the JBZoo Toolbox project. +# For the full copyright and license information, please view the LICENSE +# file that was distributed with this source code. +# +# @license MIT +# @copyright Copyright (C) JBZoo.com, All rights reserved. +# @see https://github.com/JBZoo/Csv-Blueprint +# + +.idea +.DS_Store +build +vendor +phpunit.xml +*.cache diff --git a/.phan.php b/.phan.php new file mode 100644 index 00000000..8780395e --- /dev/null +++ b/.phan.php @@ -0,0 +1,34 @@ + [ + 'src', + + 'vendor/jbzoo/data/src', + 'vendor/jbzoo/cli/src', + 'vendor/jbzoo/utils/src', + 'vendor/jbzoo/ci-report-converter/src', + 'vendor/league/csv/src', + 'vendor/fakerphp/faker/src', + 'vendor/symfony/console', + ], +]); diff --git a/LICENSE b/LICENSE index fcc81725..1183d723 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 JBZoo Toolbox +Copyright (c) 2020 JBZoo Toolbox for developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..6629f209 --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +# +# JBZoo Toolbox - Csv-Blueprint. +# +# This file is part of the JBZoo Toolbox project. +# For the full copyright and license information, please view the LICENSE +# file that was distributed with this source code. +# +# @license MIT +# @copyright Copyright (C) JBZoo.com, All rights reserved. +# @see https://github.com/JBZoo/Csv-Blueprint +# + + +ifneq (, $(wildcard ./vendor/jbzoo/codestyle/src/init.Makefile)) + include ./vendor/jbzoo/codestyle/src/init.Makefile +endif + +OUTPUT ?= table + +update: ##@Project Install/Update all 3rd party dependencies + $(call title,"Install/Update all 3rd party dependencies") + @echo "Composer flags: $(JBZOO_COMPOSER_UPDATE_FLAGS)" + @composer update $(JBZOO_COMPOSER_UPDATE_FLAGS) + + +test-all: ##@Project Run all project tests at once + @make test + @make codestyle + + +demo-valid: ##@Project Run demo valid CSV + $(call title,"Demo - Valid CSV") + @${PHP_BIN} ./csv-blueprint validate:csv \ + --csv=./tests/fixtures/demo.csv \ + --schema=./tests/schemas/demo_valid.yml + + +demo-invalid: ##@Project Run demo invalid CSV + $(call title,"Demo - Invalid CSV") + @${PHP_BIN} ./csv-blueprint validate:csv \ + --csv=./tests/fixtures/demo.csv \ + --schema=./tests/schemas/demo_invalid.yml + + +demo-github: ##@Project Run demo invalid CSV + @${PHP_BIN} ./csv-blueprint validate:csv \ + --csv=./tests/fixtures/demo.csv \ + --schema=./tests/schemas/demo_invalid.yml \ + --output=$(OUTPUT) \ + --ansi + + +demo: ##@Project Run all demo commands + @make demo-valid + @make demo-invalid diff --git a/README.md b/README.md index 7483a948..20a8749a 100644 --- a/README.md +++ b/README.md @@ -1 +1,212 @@ -# csv-validator \ No newline at end of file +# JBZoo / Csv-Blueprint + +[![CI](https://github.com/JBZoo/Csv-Blueprint/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/JBZoo/Csv-Blueprint/actions/workflows/main.yml?query=branch%3Amaster) [![Coverage Status](https://coveralls.io/repos/github/JBZoo/Csv-Blueprint/badge.svg?branch=master)](https://coveralls.io/github/JBZoo/Csv-Blueprint?branch=master) [![Psalm Coverage](https://shepherd.dev/github/JBZoo/Csv-Blueprint/coverage.svg)](https://shepherd.dev/github/JBZoo/Csv-Blueprint) [![Psalm Level](https://shepherd.dev/github/JBZoo/Csv-Blueprint/level.svg)](https://shepherd.dev/github/JBZoo/Csv-Blueprint) [![CodeFactor](https://www.codefactor.io/repository/github/jbzoo/csv-blueprint/badge)](https://www.codefactor.io/repository/github/jbzoo/csv-blueprint/issues) +[![Stable Version](https://poser.pugx.org/jbzoo/csv-blueprint/version)](https://packagist.org/packages/jbzoo/csv-blueprint/) [![Total Downloads](https://poser.pugx.org/jbzoo/csv-blueprint/downloads)](https://packagist.org/packages/jbzoo/csv-blueprint/stats) [![Dependents](https://poser.pugx.org/jbzoo/csv-blueprint/dependents)](https://packagist.org/packages/jbzoo/csv-blueprint/dependents?order_by=downloads) [![GitHub License](https://img.shields.io/github/license/jbzoo/csv-blueprint)](https://github.com/JBZoo/Csv-Blueprint/blob/master/LICENSE) + + + + +### Installing + +```sh +composer require jbzoo/csv-blueprint +``` + + +### Usage + + +### Schema file examples + +
+ Click to see: YAML format (with comment) + +```yml +# It's a full example of the CSV schema file in YAML format. + +csv: # Here are default values. You can skip this section if you don't need to override the default values + header: true # If the first row is a header. If true, name of each column is required + delimiter: , # Delimiter character in CSV file + quote_char: \ # Quote character in CSV file + enclosure: "\"" # Enclosure for each field in CSV file + encoding: utf-8 # Only utf-8, utf-16, utf-32 (Experimental) + bom: false # If the file has a BOM (Byte Order Mark) at the beginning (Experimental) + +columns: + - name: "csv_header_name" # Any custom name of the column in the CSV file (first row). Required if "csv_structure.header" is true. + description: "Lorem ipsum" # Optional. Description of the column. Not used in the validation process. + rules: + # You can use the rules in any combination. Or not use any of them. + # They are grouped below simply for ease of navigation and reading. + # If you see the value for the rule is "true" - that's just an enable flag. + # In other cases, these are rule parameters. + + # General rules + not_empty: true # Value is not empty string. Ignore spaces. + exact_value: Some string # Case-sensitive. Exact value for string in the column + allow_values: [ y, n, "" ] # Strict set of values that are allowed. Case-sensitive. + + # Strings only + regex: /^[\d]{2}$/ # Any valid regex pattern. See https://www.php.net/manual/en/reference.pcre.pattern.syntax.php + min_length: 1 # Integer only. Min length of the string with spaces + max_length: 10 # Integer only. Max length of the string with spaces + only_trimed: true # Only trimed strings. Example: "Hello World" (not " Hello World ") + only_lowercase: true # String is only lower-case. Example: "hello world" + only_uppercase: true # String is only upper-case. Example: "HELLO WORLD" + only_capitalize: true # String is only capitalized. Example: "Hello World" + + # Deciaml and integer numbers + min: 10 # Can be integer or float, negative and positive + max: 100.50 # Can be integer or float, negative and positive + precision: 2 # Strict(!) number of digits after the decimal point + + # Dates + date_format: Y-m-d # See: https://www.php.net/manual/en/datetime.format.php + min_date: "2000-01-02" # See examples https://www.php.net/manual/en/function.strtotime.php + max_date: "+1 day" # See examples https://www.php.net/manual/en/function.strtotime.php + + # Specific formats + is_bool: true # Allow only boolean values "true" and "false", case-insensitive + is_int: true # Check format only. Can be negative and positive. Without any separators + is_float: true # Check format only. Can be negative and positive. Dot as decimal separator + is_ip: true # Only IPv4. Example: "127.0.0.1" + is_url: true # Only URL format. Example: "https://example.com/page?query=string#anchor" + is_email: true # Only email format. Example: "user@example.com" + is_domain: true # Only domain name. Example: "example.com" + is_uuid4: true # Only UUID4 format. Example: "550e8400-e29b-41d4-a716-446655440000" + is_latitude: true # Can be integer or float. Example: 50.123456 + is_longitude: true # Can be integer or float. Example: -89.123456 + cardinal_direction: true # Valid cardinal direction. Examples: "N", "S", "NE", "SE", "none", "" + usa_market_name: true # Check if the value is a valid USA market name. Example: "New York, NY" + +``` + +
+ + +
+ Click to see: JSON Format + +```json +{ + "csv" : { + "header" : true, + "delimiter" : ",", + "quote_char" : "\\", + "enclosure" : "\"", + "encoding" : "utf-8", + "bom" : false + }, + "columns" : [ + { + "name" : "csv_header_name", + "description" : "Lorem ipsum", + "rules" : { + "not_empty" : true, + "exact_value" : "Some string", + "allow_values" : ["y", "n", ""], + "regex" : "\/^[\\d]{2}$\/", + "min_length" : 1, + "max_length" : 10, + "only_trimed" : true, + "only_lowercase" : true, + "only_uppercase" : true, + "only_capitalize" : true, + "min" : 10, + "max" : 100.5, + "precision" : 2, + "date_format" : "Y-m-d", + "min_date" : "2000-01-02", + "max_date" : "+1 day", + "is_bool" : true, + "is_int" : true, + "is_float" : true, + "is_ip" : true, + "is_url" : true, + "is_email" : true, + "is_domain" : true, + "is_uuid4" : true, + "is_latitude" : true, + "is_longitude" : true, + "cardinal_direction" : true, + "usa_market_name" : true + } + } + ] +} + +``` + +
+ + + +
+ Click to see: PHP Format + +```php + [ + 'header' => true, + 'delimiter' => ',', + 'quote_char' => '\\', + 'enclosure' => '"', + 'encoding' => 'utf-8', + 'bom' => false, + ], + 'columns' => [ + [ + 'name' => 'csv_header_name', + 'description' => 'Lorem ipsum', + 'rules' => [ + 'not_empty' => true, + 'exact_value' => 'Some string', + 'allow_values' => ['y', 'n', ''], + 'regex' => '/^[\\d]{2}$/', + 'min_length' => 1, + 'max_length' => 10, + 'only_trimed' => true, + 'only_lowercase' => true, + 'only_uppercase' => true, + 'only_capitalize' => true, + 'min' => 10, + 'max' => 100.5, + 'precision' => 2, + 'date_format' => 'Y-m-d', + 'min_date' => '2000-01-02', + 'max_date' => '+1 day', + 'is_bool' => true, + 'is_int' => true, + 'is_float' => true, + 'is_ip' => true, + 'is_url' => true, + 'is_email' => true, + 'is_domain' => true, + 'is_uuid4' => true, + 'is_latitude' => true, + 'is_longitude' => true, + 'cardinal_direction' => true, + 'usa_market_name' => true, + ], + ], + ], +]; + +``` + +
+ + +## Unit tests and check code style +```sh +make update +make test-all +``` + + +### License + +MIT diff --git a/build/.gitkeep b/build/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..ef26dcbe --- /dev/null +++ b/composer.json @@ -0,0 +1,63 @@ +{ + "name" : "jbzoo/csv-blueprint", + "type" : "library", + "description" : "CLI Utility for Validating and Generating CSV Files Based on Custom Rules. It ensures your data meets specified criteria, streamlining data management and integrity checks.", + "license" : "MIT", + "keywords" : [ + "jbzoo", + "csv", + "csv-validator", + "csv-validation", + "csv-generation", + "csv-format", + "csv-rules", + "csv-schema" + ], + + "authors" : [ + { + "name" : "Denis Smetannikov", + "email" : "admin@jbzoo.com", + "role" : "lead" + } + ], + + "minimum-stability" : "dev", + "prefer-stable" : true, + + "require" : { + "php" : "^8.1", + "ext-mbstring" : "*", + + "jbzoo/data" : "^7.1", + "jbzoo/cli" : "^7.1", + "jbzoo/utils" : "^7.1", + "jbzoo/ci-report-converter" : "^7.2", + "league/csv" : "^9.15", + "fakerphp/faker" : "^1.23" + }, + + "require-dev" : { + "roave/security-advisories" : "dev-latest", + "jbzoo/toolbox-dev" : "^7.1" + }, + + "autoload" : { + "psr-4" : {"JBZoo\\CsvBlueprint\\" : "src"} + }, + + "autoload-dev" : { + "psr-4" : {"JBZoo\\PHPUnit\\" : "tests"} + }, + + "config" : { + "optimize-autoloader" : true, + "allow-plugins" : {"composer/package-versions-deprecated" : true} + }, + + "extra" : { + "branch-alias" : { + "dev-master" : "7.x-dev" + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..b3c61e26 --- /dev/null +++ b/composer.lock @@ -0,0 +1,8210 @@ +{ + "_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": "aa2d64e2d78d191e4bc83a4ad90051b6", + "packages": [ + { + "name": "bluepsyduck/symfony-process-manager", + "version": "1.3.3", + "source": { + "type": "git", + "url": "https://github.com/BluePsyduck/symfony-process-manager.git", + "reference": "2988e74f063722a5c2868882a7ba41a63c83b34b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/BluePsyduck/symfony-process-manager/zipball/2988e74f063722a5c2868882a7ba41a63c83b34b", + "reference": "2988e74f063722a5c2868882a7ba41a63c83b34b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "symfony/process": "^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "bluepsyduck/test-helper": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^8.0 || ^9.0", + "rregeer/phpunit-coverage-check": "^0.3", + "squizlabs/php_codesniffer": "^3.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "BluePsyduck\\SymfonyProcessManager\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "BluePsyduck", + "email": "bluepsyduck@gmx.com" + } + ], + "description": "A process manager for Symfony processes, able to run them in parallel.", + "homepage": "https://github.com/BluePsyduck/symfony-process-manager", + "keywords": [ + "manager", + "parallel", + "process", + "symfony" + ], + "support": { + "issues": "https://github.com/BluePsyduck/symfony-process-manager/issues", + "source": "https://github.com/BluePsyduck/symfony-process-manager/tree/1.3.3" + }, + "time": "2021-12-03T21:30:28+00:00" + }, + { + "name": "fakerphp/faker", + "version": "v1.23.1", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b", + "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1" + }, + "time": "2024-01-02T13:46:09+00:00" + }, + { + "name": "jbzoo/ci-report-converter", + "version": "7.2.1", + "source": { + "type": "git", + "url": "https://github.com/JBZoo/CI-Report-Converter.git", + "reference": "b411b01d673f2d70cf8edf8693352c6ff831bd8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JBZoo/CI-Report-Converter/zipball/b411b01d673f2d70cf8edf8693352c6ff831bd8c", + "reference": "b411b01d673f2d70cf8edf8693352c6ff831bd8c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-hash": "*", + "ext-simplexml": "*", + "jbzoo/cli": "^7.1.8", + "jbzoo/data": "^7.1", + "jbzoo/markdown": "^7.0", + "jbzoo/utils": "^7.1", + "php": "^8.1", + "symfony/console": ">=6.4" + }, + "require-dev": { + "jbzoo/mermaid-php": "^7.2", + "jbzoo/toolbox-dev": "^7.1", + "roave/security-advisories": "dev-master" + }, + "bin": [ + "ci-report-converter" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "JBZoo\\CIReportConverter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Denis Smetannikov", + "email": "admin@jbzoo.com", + "role": "lead" + } + ], + "description": "The tool converts different error reporting standards for deep integration with popular CI systems (TeamCity, IntelliJ IDEA, GitHub Actions, etc)", + "keywords": [ + "Codestyle", + "Github Actions", + "IntelliJ IDEA", + "PHPStan", + "actions", + "checkstyle", + "ci", + "continuous integration", + "github", + "inspections", + "junit", + "phan", + "phpcs", + "phploc", + "phpmd", + "phpmnd", + "phpstorm", + "pmd", + "psalm", + "teamcity", + "teamcity-inspections", + "tests" + ], + "support": { + "issues": "https://github.com/JBZoo/CI-Report-Converter/issues", + "source": "https://github.com/JBZoo/CI-Report-Converter/tree/7.2.1" + }, + "time": "2024-01-28T14:03:00+00:00" + }, + { + "name": "jbzoo/cli", + "version": "7.1.8", + "source": { + "type": "git", + "url": "https://github.com/JBZoo/Cli.git", + "reference": "7577c4d88d9724103269696a4c7726ec68211279" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JBZoo/Cli/zipball/7577c4d88d9724103269696a4c7726ec68211279", + "reference": "7577c4d88d9724103269696a4c7726ec68211279", + "shasum": "" + }, + "require": { + "bluepsyduck/symfony-process-manager": ">=1.3.3", + "jbzoo/event": "^7.0", + "jbzoo/utils": "^7.1", + "monolog/monolog": "^3.4", + "php": "^8.1", + "symfony/console": ">=6.4", + "symfony/lock": ">=6.4", + "symfony/process": ">=6.4" + }, + "require-dev": { + "jbzoo/toolbox-dev": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "JBZoo\\Cli\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Denis Smetannikov", + "email": "admin@jbzoo.com", + "role": "lead" + } + ], + "description": "The framework helps create CLI tools and provides new tools for symfony/console, symfony/process.", + "keywords": [ + "ELK", + "cli", + "command-line", + "console", + "console-application", + "cron", + "crontab", + "elastic", + "elk-stack", + "jbzoo", + "logstash", + "process", + "symfony", + "symfony-console", + "symfony-process", + "terminal" + ], + "support": { + "issues": "https://github.com/JBZoo/Cli/issues", + "source": "https://github.com/JBZoo/Cli/tree/7.1.8" + }, + "time": "2024-01-28T13:57:00+00:00" + }, + { + "name": "jbzoo/data", + "version": "7.1.1", + "source": { + "type": "git", + "url": "https://github.com/JBZoo/Data.git", + "reference": "8666e8cdc912c3fd6176aa0ca5ab29bd1a7d0ab2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JBZoo/Data/zipball/8666e8cdc912c3fd6176aa0ca5ab29bd1a7d0ab2", + "reference": "8666e8cdc912c3fd6176aa0ca5ab29bd1a7d0ab2", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^8.1" + }, + "require-dev": { + "jbzoo/toolbox-dev": "^7.1", + "jbzoo/utils": "^7.1.1", + "symfony/polyfill-ctype": ">=1.28.0", + "symfony/polyfill-mbstring": ">=1.28.0", + "symfony/polyfill-php73": ">=1.28.0", + "symfony/polyfill-php80": ">=1.28.0", + "symfony/polyfill-php81": ">=1.28.0", + "symfony/yaml": ">=6.4" + }, + "suggest": { + "jbzoo/utils": ">=7.1", + "symfony/yaml": ">=6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "JBZoo\\Data\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Denis Smetannikov", + "email": "admin@jbzoo.com", + "role": "lead" + } + ], + "description": "An extended version of the ArrayObject object for working with system settings or just for working with data arrays", + "keywords": [ + "array", + "arrayobject", + "config", + "data", + "ini", + "json", + "params", + "yml" + ], + "support": { + "issues": "https://github.com/JBZoo/Data/issues", + "source": "https://github.com/JBZoo/Data/tree/7.1.1" + }, + "time": "2024-01-28T08:47:08+00:00" + }, + { + "name": "jbzoo/event", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/JBZoo/Event.git", + "reference": "09c87f83acc79252cc7f01b173c4c6eb399e62a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JBZoo/Event/zipball/09c87f83acc79252cc7f01b173c4c6eb399e62a1", + "reference": "09c87f83acc79252cc7f01b173c4c6eb399e62a1", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "jbzoo/data": "^7.1", + "jbzoo/toolbox-dev": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "JBZoo\\Event\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Denis Smetannikov", + "email": "admin@jbzoo.com", + "role": "lead" + }, + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "https://sabre.io/event/" + } + ], + "description": "Library for event-based development", + "keywords": [ + "HOOK", + "emit", + "emitter", + "event-manager", + "eventmanager", + "events", + "jbzoo", + "listener", + "observer", + "signal" + ], + "support": { + "issues": "https://github.com/JBZoo/Event/issues", + "source": "https://github.com/JBZoo/Event/tree/7.0.1" + }, + "time": "2024-01-28T08:57:37+00:00" + }, + { + "name": "jbzoo/markdown", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/JBZoo/Markdown.git", + "reference": "02e9d756ed91d33c63a7794db1279af56e4da5e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JBZoo/Markdown/zipball/02e9d756ed91d33c63a7794db1279af56e4da5e9", + "reference": "02e9d756ed91d33c63a7794db1279af56e4da5e9", + "shasum": "" + }, + "require": { + "jbzoo/utils": "^7.1", + "php": "^8.1" + }, + "require-dev": { + "jbzoo/toolbox-dev": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "JBZoo\\Markdown\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Denis Smetannikov", + "email": "admin@jbzoo.com", + "role": "lead" + } + ], + "description": "Tools to render markdown text from PHP code", + "keywords": [ + "Rendering", + "jbzoo", + "markdown", + "readme", + "text" + ], + "support": { + "issues": "https://github.com/JBZoo/Markdown/issues", + "source": "https://github.com/JBZoo/Markdown/tree/7.0.1" + }, + "time": "2024-01-28T12:43:57+00:00" + }, + { + "name": "jbzoo/utils", + "version": "7.1.2", + "source": { + "type": "git", + "url": "https://github.com/JBZoo/Utils.git", + "reference": "55ddbe0558f2e4a8f69b4469d9ead97f2de5e13f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JBZoo/Utils/zipball/55ddbe0558f2e4a8f69b4469d9ead97f2de5e13f", + "reference": "55ddbe0558f2e4a8f69b4469d9ead97f2de5e13f", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-filter": "*", + "ext-gd": "*", + "ext-posix": "*", + "php": "^8.1" + }, + "require-dev": { + "jbzoo/data": "^7.1", + "jbzoo/toolbox-dev": "^7.1", + "symfony/process": ">=6.4" + }, + "suggest": { + "ext-intl": "*", + "ext-mbstring": "Provides multibyte specific string functions", + "jbzoo/data": ">=4.0", + "symfony/polyfill-mbstring": "For UTF-8 if ext-mbstring disabled", + "symfony/process": "For Cli::exec() method only" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "files": [ + "src/defines.php", + "src/aliases.php" + ], + "psr-4": { + "JBZoo\\Utils\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Denis Smetannikov", + "email": "admin@jbzoo.com", + "role": "lead" + }, + { + "name": "Brandon Wamboldt", + "email": "brandon.wamboldt@gmail.com" + }, + { + "name": "Luís Nóbrega", + "email": "luis.barros.nobrega@gmail.com" + } + ], + "description": "Collection of PHP functions, mini classes and snippets for everyday developer's routine life.", + "keywords": [ + "array", + "cli", + "collection", + "command line", + "dates", + "email", + "env", + "environment", + "filesystem", + "filter", + "helper", + "helpers", + "http", + "image", + "mbstring", + "misc", + "serialize", + "slugify", + "string", + "timer", + "url", + "utility", + "utils" + ], + "support": { + "issues": "https://github.com/JBZoo/Utils/issues", + "source": "https://github.com/JBZoo/Utils/tree/7.1.2" + }, + "time": "2024-01-28T08:37:18+00:00" + }, + { + "name": "league/csv", + "version": "9.15.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/csv.git", + "reference": "fa7e2441c0bc9b2360f4314fd6c954f7ff40d435" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/csv/zipball/fa7e2441c0bc9b2360f4314fd6c954f7ff40d435", + "reference": "fa7e2441c0bc9b2360f4314fd6c954f7ff40d435", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "ext-json": "*", + "ext-mbstring": "*", + "php": "^8.1.2" + }, + "require-dev": { + "doctrine/collections": "^2.1.4", + "ext-dom": "*", + "ext-xdebug": "*", + "friendsofphp/php-cs-fixer": "^v3.22.0", + "phpbench/phpbench": "^1.2.15", + "phpstan/phpstan": "^1.10.57", + "phpstan/phpstan-deprecation-rules": "^1.1.4", + "phpstan/phpstan-phpunit": "^1.3.15", + "phpstan/phpstan-strict-rules": "^1.5.2", + "phpunit/phpunit": "^10.5.9", + "symfony/var-dumper": "^6.4.2" + }, + "suggest": { + "ext-dom": "Required to use the XMLConverter and the HTMLConverter classes", + "ext-iconv": "Needed to ease transcoding CSV using iconv stream filters" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "League\\Csv\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://github.com/nyamsprod/", + "role": "Developer" + } + ], + "description": "CSV data manipulation made easy in PHP", + "homepage": "https://csv.thephpleague.com", + "keywords": [ + "convert", + "csv", + "export", + "filter", + "import", + "read", + "transform", + "write" + ], + "support": { + "docs": "https://csv.thephpleague.com", + "issues": "https://github.com/thephpleague/csv/issues", + "rss": "https://github.com/thephpleague/csv/releases.atom", + "source": "https://github.com/thephpleague/csv" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-02-20T20:00:00+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.5.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c915e2634718dbc8a4a15c61b0e62e7a44e14448", + "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "^10.1", + "predis/predis": "^1.1 || ^2", + "ruflin/elastica": "^7", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.5.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2023-10-27T15:32:31+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/log", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376", + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.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/2.0.0" + }, + "time": "2021-07-14T16:41:46+00:00" + }, + { + "name": "symfony/console", + "version": "v6.4.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "0d9e4eb5ad413075624378f474c4167ea202de78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/0d9e4eb5ad413075624378f474c4167ea202de78", + "reference": "0d9e4eb5ad413075624378f474c4167ea202de78", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "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/v6.4.4" + }, + "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-02-22T20:27:10+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "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.4.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": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/lock", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/lock.git", + "reference": "1cabf3cc775b1aa6008ebd471fa773444af4e956" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/lock/zipball/1cabf3cc775b1aa6008ebd471fa773444af4e956", + "reference": "1cabf3cc775b1aa6008ebd471fa773444af4e956", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/dbal": "<2.13", + "symfony/cache": "<6.2" + }, + "require-dev": { + "doctrine/dbal": "^2.13|^3|^4", + "predis/predis": "^1.1|^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Lock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jérémy Derussé", + "email": "jeremy@derusse.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Creates and manages locks, a mechanism to provide exclusive access to a shared resource", + "homepage": "https://symfony.com", + "keywords": [ + "cas", + "flock", + "locking", + "mutex", + "redlock", + "semaphore" + ], + "support": { + "source": "https://github.com/symfony/lock/tree/v6.4.3" + }, + "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-01-23T14:51:35+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/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.29.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-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/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.29.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-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/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.29.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-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/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.29.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-01-29T20:11:03+00:00" + }, + { + "name": "symfony/process", + "version": "v6.4.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "710e27879e9be3395de2b98da3f52a946039f297" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/710e27879e9be3395de2b98da3f52a946039f297", + "reference": "710e27879e9be3395de2b98da3f52a946039f297", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "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": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.4.4" + }, + "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-02-20T12:31:00+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "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.4.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-12-26T14:02:43+00:00" + }, + { + "name": "symfony/string", + "version": "v6.4.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", + "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^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/v6.4.4" + }, + "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-02-01T13:16:41+00:00" + } + ], + "packages-dev": [ + { + "name": "amphp/amp", + "version": "v2.6.2", + "source": { + "type": "git", + "url": "https://github.com/amphp/amp.git", + "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", + "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^7 | ^8 | ^9", + "psalm/phar": "^3.11@dev", + "react/promise": "^2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "files": [ + "lib/functions.php", + "lib/Internal/functions.php" + ], + "psr-4": { + "Amp\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "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": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/v2.6.2" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2022-02-20T17:52:18+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v1.8.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd", + "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd", + "shasum": "" + }, + "require": { + "amphp/amp": "^2", + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1.4", + "friendsofphp/php-cs-fixer": "^2.3", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^6 || ^7 || ^8", + "psalm/phar": "^3.11.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Amp\\ByteStream\\": "lib" + } + }, + "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": "http://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/byte-stream/issues", + "source": "https://github.com/amphp/byte-stream/tree/v1.8.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2021-03-30T17:13:30+00:00" + }, + { + "name": "composer/pcre", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "4775f35b2d70865807c89d32c8e7385b86eb0ace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/4775f35b2d70865807c89d32c8e7385b86eb0ace", + "reference": "4775f35b2d70865807c89d32c8e7385b86eb0ace", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "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.1.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-03-07T15:38:35+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "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.0" + }, + "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": "2023-08-31T09:50:34+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "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", + "symfony/phpunit-bridge": "^6.0" + }, + "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": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.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": "2022-02-25T21:32:43+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.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "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.3" + }, + "time": "2024-01-30T19:34:25+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:23:10+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "php": "^7.1 || ^8.0", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + }, + "time": "2021-06-11T22:34:44+00:00" + }, + { + "name": "felixfbecker/language-server-protocol", + "version": "v1.5.2", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-language-server-protocol.git", + "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842", + "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842", + "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.2" + }, + "time": "2022-03-02T22:36:06+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "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.1.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-02-07T09:43:46+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.51.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "127fa74f010da99053e3f5b62672615b72dd6efd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/127fa74f010da99053e3f5b62672615b72dd6efd", + "reference": "127fa74f010da99053e3f5b62672615b72dd6efd", + "shasum": "" + }, + "require": { + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3 || ^2.0", + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.7", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", + "phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2", + "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.51.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2024-02-28T19:50:06+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:35:24+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:19:20+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.6.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.6.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:05:35+00:00" + }, + { + "name": "jbzoo/codestyle", + "version": "7.1.0", + "source": { + "type": "git", + "url": "https://github.com/JBZoo/Codestyle.git", + "reference": "50c3261d9d566d1e1f94b34b8c2a2ef64e035b0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JBZoo/Codestyle/zipball/50c3261d9d566d1e1f94b34b8c2a2ef64e035b0c", + "reference": "50c3261d9d566d1e1f94b34b8c2a2ef64e035b0c", + "shasum": "" + }, + "require": { + "friendsofphp/php-cs-fixer": ">=3.48.0", + "jbzoo/data": "^7.1", + "kubawerlos/php-cs-fixer-custom-fixers": ">=3.19.2", + "nikic/php-parser": ">=4.18.0", + "pdepend/pdepend": ">=2.16.2", + "phan/phan": ">=5.4.3", + "php": "^8.1", + "phpmd/phpmd": ">=2.15.0", + "phpmetrics/phpmetrics": ">=2.8.2", + "phpstan/phpstan": ">=1.10.57", + "phpstan/phpstan-strict-rules": ">=1.5.2", + "povils/phpmnd": ">=3.4.0", + "squizlabs/php_codesniffer": ">=3.8.1", + "symfony/console": ">=6.4", + "symfony/finder": ">=6.4", + "symfony/yaml": ">=6.4", + "vimeo/psalm": ">=5.20.0" + }, + "require-dev": { + "jbzoo/phpunit": "^7.0", + "jbzoo/utils": "^7.1.1", + "symfony/var-dumper": ">=6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "files": [ + "src/compatibility.php" + ], + "psr-4": { + "JBZoo\\Codestyle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Denis Smetannikov", + "email": "admin@jbzoo.com", + "role": "lead" + } + ], + "description": "Collection of QA tools and JBZoo code standards", + "keywords": [ + "Codestyle", + "PHPStan", + "coding-standard", + "jbzoo", + "phan", + "php", + "php-cs-fixer", + "phpcompatibility", + "phpcs", + "phpmd", + "phpmetrics", + "phpunit", + "psalm", + "qa", + "tests" + ], + "support": { + "issues": "https://github.com/JBZoo/Codestyle/issues", + "source": "https://github.com/JBZoo/Codestyle/tree/7.1.0" + }, + "time": "2024-01-27T21:57:08+00:00" + }, + { + "name": "jbzoo/jbdump", + "version": "1.5.6", + "source": { + "type": "git", + "url": "https://github.com/JBZoo/JBDump.git", + "reference": "044e1f9f648d2467d9161732f1195a44d452ca50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JBZoo/JBDump/zipball/044e1f9f648d2467d9161732f1195a44d452ca50", + "reference": "044e1f9f648d2467d9161732f1195a44d452ca50", + "shasum": "" + }, + "require": { + "php": ">=5.3.10" + }, + "replace": { + "smetdenis/jbdump": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "autoload.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "SmetDenis", + "email": "admin@jbzoo.com" + }, + { + "name": "Kaloyan K. Tsvetkov", + "email": "kaloyan@kaloyan.info" + }, + { + "name": "Jeremy Dorn", + "email": "jeremy@jeremydorn.com" + }, + { + "name": "Florin Patan", + "email": "florinpatan@gmail.com" + } + ], + "description": "Script for debug and dump PHP variables and other stuff. This tool is a nice replacement for print_r() and var_dump() functions.", + "keywords": [ + "debug", + "debugging", + "dump", + "dumper", + "jbdump", + "krumo", + "php", + "pretty", + "print", + "print_r", + "var_dump", + "vars" + ], + "support": { + "issues": "https://github.com/JBZoo/JBDump/issues", + "source": "https://github.com/JBZoo/JBDump/tree/1.5.6" + }, + "time": "2021-03-31T09:21:47+00:00" + }, + { + "name": "jbzoo/phpunit", + "version": "7.1.0", + "source": { + "type": "git", + "url": "https://github.com/JBZoo/PHPUnit.git", + "reference": "4a70dd033b90a08498cbd7147a1c3150198f51f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JBZoo/PHPUnit/zipball/4a70dd033b90a08498cbd7147a1c3150198f51f8", + "reference": "4a70dd033b90a08498cbd7147a1c3150198f51f8", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "ext-mbstring": "*", + "jbzoo/markdown": "^7.0", + "php": "^8.1", + "phpunit/phpunit": "^9.6.16", + "ulrichsg/getopt-php": ">=4.0.3" + }, + "require-dev": { + "guzzlehttp/guzzle": ">=7.8.1", + "jbzoo/codestyle": "^7.1", + "jbzoo/data": "^7.1", + "jbzoo/http-client": "^7.0", + "jbzoo/toolbox-dev": "^7.0", + "jbzoo/utils": "^7.1", + "symfony/process": ">=6.4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions/defines.php", + "src/functions/aliases.php", + "src/functions/tools.php" + ], + "psr-4": { + "JBZoo\\PHPUnit\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Denis Smetannikov", + "email": "admin@jbzoo.com", + "role": "lead" + } + ], + "description": "PHPUnit toolbox with short assert aliases and useful functions around testing", + "keywords": [ + "aliases", + "assert", + "assertion", + "debug", + "jbzoo", + "phpunit", + "short-syntax", + "testing" + ], + "support": { + "issues": "https://github.com/JBZoo/PHPUnit/issues", + "source": "https://github.com/JBZoo/PHPUnit/tree/7.1.0" + }, + "time": "2024-01-27T22:11:15+00:00" + }, + { + "name": "jbzoo/toolbox-dev", + "version": "7.1.0", + "source": { + "type": "git", + "url": "https://github.com/JBZoo/Toolbox-Dev.git", + "reference": "1048efcb712eb2392e19e1b30201d191a97d66ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JBZoo/Toolbox-Dev/zipball/1048efcb712eb2392e19e1b30201d191a97d66ca", + "reference": "1048efcb712eb2392e19e1b30201d191a97d66ca", + "shasum": "" + }, + "require": { + "fakerphp/faker": ">=1.23.0", + "jbzoo/codestyle": "^7.1", + "jbzoo/jbdump": ">=1.5.6|^7.0", + "jbzoo/markdown": "^7.0", + "jbzoo/phpunit": "^7.1", + "php": "^8.1", + "php-coveralls/php-coveralls": ">=2.7.0", + "symfony/var-dumper": ">=6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "files": [ + "src/var-dumper.php" + ], + "psr-4": { + "JBZoo\\ToolboxDev\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Denis Smetannikov", + "email": "admin@jbzoo.com", + "role": "lead" + } + ], + "description": "Developer toolbox only for JBZoo libs on github+travis", + "keywords": [ + "Toolbox", + "debug", + "dev", + "dev-kit", + "developer", + "devkit", + "jbzoo" + ], + "support": { + "issues": "https://github.com/JBZoo/Toolbox-Dev/issues", + "source": "https://github.com/JBZoo/Toolbox-Dev/tree/7.1.0" + }, + "time": "2024-01-27T22:19:13+00:00" + }, + { + "name": "kubawerlos/php-cs-fixer-custom-fixers", + "version": "v3.21.0", + "source": { + "type": "git", + "url": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers.git", + "reference": "3d1bb75be0df6c6fba4487c75b9e425a2c1d27c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kubawerlos/php-cs-fixer-custom-fixers/zipball/3d1bb75be0df6c6fba4487c75b9e425a2c1d27c9", + "reference": "3d1bb75be0df6c6fba4487c75b9e425a2c1d27c9", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "ext-tokenizer": "*", + "friendsofphp/php-cs-fixer": "^3.50", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6.4 || ^10.0.14" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpCsFixerCustomFixers\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kuba Werłos", + "email": "werlos@gmail.com" + } + ], + "description": "A set of custom fixers for PHP CS Fixer", + "support": { + "issues": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/issues", + "source": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/tree/v3.21.0" + }, + "time": "2024-02-24T08:53:34+00:00" + }, + { + "name": "microsoft/tolerant-php-parser", + "version": "v0.1.2", + "source": { + "type": "git", + "url": "https://github.com/microsoft/tolerant-php-parser.git", + "reference": "3eccfd273323aaf69513e2f1c888393f5947804b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/microsoft/tolerant-php-parser/zipball/3eccfd273323aaf69513e2f1c888393f5947804b", + "reference": "3eccfd273323aaf69513e2f1c888393f5947804b", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.15" + }, + "type": "library", + "autoload": { + "psr-4": { + "Microsoft\\PhpParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Lourens", + "email": "roblou@microsoft.com" + } + ], + "description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios", + "support": { + "issues": "https://github.com/microsoft/tolerant-php-parser/issues", + "source": "https://github.com/microsoft/tolerant-php-parser/tree/v0.1.2" + }, + "time": "2022-10-05T17:30:19+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "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", + "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.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v4.4.1", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/132c75c7dd83e45353ebb9c6c9f591952995bbf0", + "reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0", + "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/v4.4.1" + }, + "time": "2024-01-31T06:18:54+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.18.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-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/v4.18.0" + }, + "time": "2023-12-10T21:03:43+00:00" + }, + { + "name": "pdepend/pdepend", + "version": "2.16.2", + "source": { + "type": "git", + "url": "https://github.com/pdepend/pdepend.git", + "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/f942b208dc2a0868454d01b29f0c75bbcfc6ed58", + "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58", + "shasum": "" + }, + "require": { + "php": ">=5.3.7", + "symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0", + "symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0", + "symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0", + "symfony/polyfill-mbstring": "^1.19" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0|^1.2.3", + "gregwar/rst": "^1.0", + "squizlabs/php_codesniffer": "^2.0.0" + }, + "bin": [ + "src/bin/pdepend" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "PDepend\\": "src/main/php/PDepend" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Official version of pdepend to be handled with Composer", + "keywords": [ + "PHP Depend", + "PHP_Depend", + "dev", + "pdepend" + ], + "support": { + "issues": "https://github.com/pdepend/pdepend/issues", + "source": "https://github.com/pdepend/pdepend/tree/2.16.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend", + "type": "tidelift" + } + ], + "time": "2023-12-17T18:09:59+00:00" + }, + { + "name": "phan/phan", + "version": "5.4.3", + "source": { + "type": "git", + "url": "https://github.com/phan/phan.git", + "reference": "86a7acd99c1239b8867b49feca2398851212e7fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phan/phan/zipball/86a7acd99c1239b8867b49feca2398851212e7fe", + "reference": "86a7acd99c1239b8867b49feca2398851212e7fe", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4|^2.0|^3.0", + "composer/xdebug-handler": "^2.0|^3.0", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.0.4", + "microsoft/tolerant-php-parser": "0.1.2", + "netresearch/jsonmapper": "^1.6.0|^2.0|^3.0|^4.0", + "php": "^7.2.0|^8.0.0", + "sabre/event": "^5.1.3", + "symfony/console": "^3.2|^4.0|^5.0|^6.0|^7.0", + "symfony/polyfill-mbstring": "^1.11.0", + "symfony/polyfill-php80": "^1.20.0", + "tysonandre/var_representation_polyfill": "^0.0.2|^0.1.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.0" + }, + "suggest": { + "ext-ast": "Needed for parsing ASTs (unless --use-fallback-parser is used). 1.0.1+ is needed, 1.0.16+ is recommended.", + "ext-iconv": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-igbinary": "Improves performance of polyfill when ext-ast is unavailable", + "ext-mbstring": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-tokenizer": "Needed for fallback/polyfill parser support and file/line-based suppressions.", + "ext-var_representation": "Suggested for converting values to strings in issue messages" + }, + "bin": [ + "phan", + "phan_client", + "tocheckstyle" + ], + "type": "project", + "autoload": { + "psr-4": { + "Phan\\": "src/Phan" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + }, + { + "name": "Rasmus Lerdorf" + }, + { + "name": "Andrew S. Morrison" + } + ], + "description": "A static analyzer for PHP", + "keywords": [ + "analyzer", + "php", + "static", + "static analysis" + ], + "support": { + "issues": "https://github.com/phan/phan/issues", + "source": "https://github.com/phan/phan/tree/5.4.3" + }, + "time": "2023-12-26T17:57:35+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": "php-coveralls/php-coveralls", + "version": "v2.7.0", + "source": { + "type": "git", + "url": "https://github.com/php-coveralls/php-coveralls.git", + "reference": "b36fa4394e519dafaddc04ae03976bc65a25ba15" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/b36fa4394e519dafaddc04ae03976bc65a25ba15", + "reference": "b36fa4394e519dafaddc04ae03976bc65a25ba15", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^6.0 || ^7.0", + "php": "^7.0 || ^8.0", + "psr/log": "^1.0 || ^2.0", + "symfony/config": "^2.1 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", + "symfony/console": "^2.1 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", + "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", + "symfony/yaml": "^2.0.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0 || ^7.0 || >=8.0 <8.5.29 || >=9.0 <9.5.23", + "sanmai/phpunit-legacy-adapter": "^6.1 || ^8.0" + }, + "suggest": { + "symfony/http-kernel": "Allows Symfony integration" + }, + "bin": [ + "bin/php-coveralls" + ], + "type": "library", + "autoload": { + "psr-4": { + "PhpCoveralls\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kitamura Satoshi", + "email": "with.no.parachute@gmail.com", + "homepage": "https://www.facebook.com/satooshi.jp", + "role": "Original creator" + }, + { + "name": "Takashi Matsuo", + "email": "tmatsuo@google.com" + }, + { + "name": "Google Inc" + }, + { + "name": "Dariusz Ruminski", + "email": "dariusz.ruminski@gmail.com", + "homepage": "https://github.com/keradus" + }, + { + "name": "Contributors", + "homepage": "https://github.com/php-coveralls/php-coveralls/graphs/contributors" + } + ], + "description": "PHP client library for Coveralls API", + "homepage": "https://github.com/php-coveralls/php-coveralls", + "keywords": [ + "ci", + "coverage", + "github", + "test" + ], + "support": { + "issues": "https://github.com/php-coveralls/php-coveralls/issues", + "source": "https://github.com/php-coveralls/php-coveralls/tree/v2.7.0" + }, + "time": "2023-11-22T10:21:01+00:00" + }, + { + "name": "php-parallel-lint/php-console-color", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-parallel-lint/PHP-Console-Color.git", + "reference": "7adfefd530aa2d7570ba87100a99e2483a543b88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-parallel-lint/PHP-Console-Color/zipball/7adfefd530aa2d7570ba87100a99e2483a543b88", + "reference": "7adfefd530aa2d7570ba87100a99e2483a543b88", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "replace": { + "jakub-onderka/php-console-color": "*" + }, + "require-dev": { + "php-parallel-lint/php-code-style": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.0", + "php-parallel-lint/php-var-dump-check": "0.*", + "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHP_Parallel_Lint\\PhpConsoleColor\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Jakub Onderka", + "email": "jakub.onderka@gmail.com" + } + ], + "description": "Simple library for creating colored console ouput.", + "support": { + "issues": "https://github.com/php-parallel-lint/PHP-Console-Color/issues", + "source": "https://github.com/php-parallel-lint/PHP-Console-Color/tree/v1.0.1" + }, + "time": "2021-12-25T06:49:29+00:00" + }, + { + "name": "php-parallel-lint/php-console-highlighter", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-parallel-lint/PHP-Console-Highlighter.git", + "reference": "5b4803384d3303cf8e84141039ef56c8a123138d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-parallel-lint/PHP-Console-Highlighter/zipball/5b4803384d3303cf8e84141039ef56c8a123138d", + "reference": "5b4803384d3303cf8e84141039ef56c8a123138d", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.2", + "php-parallel-lint/php-console-color": "^1.0.1" + }, + "replace": { + "jakub-onderka/php-console-highlighter": "*" + }, + "require-dev": { + "php-parallel-lint/php-code-style": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.0", + "php-parallel-lint/php-var-dump-check": "0.*", + "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHP_Parallel_Lint\\PhpConsoleHighlighter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jakub Onderka", + "email": "acci@acci.cz", + "homepage": "http://www.acci.cz/" + } + ], + "description": "Highlight PHP code in terminal", + "support": { + "issues": "https://github.com/php-parallel-lint/PHP-Console-Highlighter/issues", + "source": "https://github.com/php-parallel-lint/PHP-Console-Highlighter/tree/v1.0.0" + }, + "time": "2022-02-18T08:23:19+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.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "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": "account@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.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "153ae662783729388a584b4361f2545e4d841e3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", + "reference": "153ae662783729388a584b4361f2545e4d841e3c", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" + }, + "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.8.2" + }, + "time": "2024-02-23T11:10:43+00:00" + }, + { + "name": "phpmd/phpmd", + "version": "2.15.0", + "source": { + "type": "git", + "url": "https://github.com/phpmd/phpmd.git", + "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/74a1f56e33afad4128b886e334093e98e1b5e7c0", + "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0", + "ext-xml": "*", + "pdepend/pdepend": "^2.16.1", + "php": ">=5.3.9" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0 || ^1.3.2", + "ext-json": "*", + "ext-simplexml": "*", + "gregwar/rst": "^1.0", + "mikey179/vfsstream": "^1.6.8", + "squizlabs/php_codesniffer": "^2.9.2 || ^3.7.2" + }, + "bin": [ + "src/bin/phpmd" + ], + "type": "library", + "autoload": { + "psr-0": { + "PHPMD\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Manuel Pichler", + "email": "github@manuel-pichler.de", + "homepage": "https://github.com/manuelpichler", + "role": "Project Founder" + }, + { + "name": "Marc Würth", + "email": "ravage@bluewin.ch", + "homepage": "https://github.com/ravage84", + "role": "Project Maintainer" + }, + { + "name": "Other contributors", + "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", + "role": "Contributors" + } + ], + "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", + "homepage": "https://phpmd.org/", + "keywords": [ + "dev", + "mess detection", + "mess detector", + "pdepend", + "phpmd", + "pmd" + ], + "support": { + "irc": "irc://irc.freenode.org/phpmd", + "issues": "https://github.com/phpmd/phpmd/issues", + "source": "https://github.com/phpmd/phpmd/tree/2.15.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd", + "type": "tidelift" + } + ], + "time": "2023-12-11T08:22:20+00:00" + }, + { + "name": "phpmetrics/phpmetrics", + "version": "v2.8.2", + "source": { + "type": "git", + "url": "https://github.com/phpmetrics/PhpMetrics.git", + "reference": "4b77140a11452e63c7a9b98e0648320bf6710090" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmetrics/PhpMetrics/zipball/4b77140a11452e63c7a9b98e0648320bf6710090", + "reference": "4b77140a11452e63c7a9b98e0648320bf6710090", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^3|^4", + "php": ">=5.5" + }, + "replace": { + "halleck45/php-metrics": "*", + "halleck45/phpmetrics": "*" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14", + "sebastian/comparator": ">=1.2.3", + "squizlabs/php_codesniffer": "^3.5", + "symfony/dom-crawler": "^3.0 || ^4.0 || ^5.0" + }, + "bin": [ + "bin/phpmetrics" + ], + "type": "library", + "autoload": { + "files": [ + "./src/functions.php" + ], + "psr-0": { + "Hal\\": "./src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jean-François Lépine", + "email": "lepinejeanfrancois@yahoo.fr", + "homepage": "http://www.lepine.pro", + "role": "Copyright Holder" + } + ], + "description": "Static analyzer tool for PHP : Coupling, Cyclomatic complexity, Maintainability Index, Halstead's metrics... and more !", + "homepage": "http://www.phpmetrics.org", + "keywords": [ + "analysis", + "qa", + "quality", + "testing" + ], + "support": { + "issues": "https://github.com/PhpMetrics/PhpMetrics/issues", + "source": "https://github.com/phpmetrics/PhpMetrics/tree/v2.8.2" + }, + "time": "2023-03-08T15:03:36+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.26.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "231e3186624c03d7e7c890ec662b81e6b0405227" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/231e3186624c03d7e7c890ec662b81e6b0405227", + "reference": "231e3186624c03d7e7c890ec662b81e6b0405227", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "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/1.26.0" + }, + "time": "2024-02-23T16:05:55+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.10.60", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/95dcea7d6c628a3f2f56d091d8a0219485a86bbe", + "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2024-03-07T13:30:19+00:00" + }, + { + "name": "phpstan/phpstan-strict-rules", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-strict-rules.git", + "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/7a50e9662ee9f3942e4aaaf3d603653f60282542", + "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.10.34" + }, + "require-dev": { + "nikic/php-parser": "^4.13.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Extra strict and opinionated rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.2" + }, + "time": "2023-10-30T14:35:06+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.31", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", + "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "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-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library 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/9.2.31" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:37:42+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "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", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.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": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.6.17", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "1a156980d78a6666721b7e8e8502fe210b587fcd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1a156980d78a6666721b7e8e8502fe210b587fcd", + "reference": "1a156980d78a6666721b7e8e8502fe210b587fcd", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1 || ^2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.28", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.5", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.2", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.6-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/9.6.17" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-02-23T13:14:51+00:00" + }, + { + "name": "povils/phpmnd", + "version": "v3.4.1", + "source": { + "type": "git", + "url": "https://github.com/povils/phpmnd.git", + "reference": "1f3eb869e3a2c4fddbe0995fddd97b75caa2c203" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/povils/phpmnd/zipball/1f3eb869e3a2c4fddbe0995fddd97b75caa2c203", + "reference": "1f3eb869e3a2c4fddbe0995fddd97b75caa2c203", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": "^7.4 || ^8.0", + "php-parallel-lint/php-console-highlighter": "^1.0", + "phpunit/php-timer": "^2.0||^3.0||^4.0||^5.0||^6.0", + "symfony/console": "^4.4 || ^5.0 || ^6.0 || ^7.0", + "symfony/finder": "^4.4 || ^5.0 || ^6.0 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6", + "squizlabs/php_codesniffer": "^2.8.1||^3.5" + }, + "bin": [ + "bin/phpmnd" + ], + "type": "application", + "autoload": { + "psr-4": { + "Povils\\PHPMND\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Povilas Susinskas", + "email": "povilassusinskas@gmail.com" + } + ], + "description": "A tool to detect Magic numbers in codebase", + "support": { + "issues": "https://github.com/povils/phpmnd/issues", + "source": "https://github.com/povils/phpmnd/tree/v3.4.1" + }, + "time": "2024-03-02T17:53:44+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "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": "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/tree/1.0.2" + }, + "time": "2023-04-10T20:10:41+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": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "roave/security-advisories", + "version": "dev-latest", + "source": { + "type": "git", + "url": "https://github.com/Roave/SecurityAdvisories.git", + "reference": "83b3589bb774f27084c7f358c13f465d94afa036" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/83b3589bb774f27084c7f358c13f465d94afa036", + "reference": "83b3589bb774f27084c7f358c13f465d94afa036", + "shasum": "" + }, + "conflict": { + "3f/pygmentize": "<1.2", + "admidio/admidio": "<4.2.13", + "adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3", + "aheinze/cockpit": "<2.2", + "aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5", + "airesvsg/acf-to-rest-api": "<=3.1", + "akaunting/akaunting": "<2.1.13", + "akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53", + "alextselegidis/easyappointments": "<1.5", + "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", + "amazing/media2click": ">=1,<1.3.3", + "amphp/artax": "<1.0.6|>=2,<2.0.6", + "amphp/http": "<1.0.1", + "amphp/http-client": ">=4,<4.4", + "anchorcms/anchor-cms": "<=0.12.7", + "andreapollastri/cipi": "<=3.1.15", + "andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5", + "apache-solr-for-typo3/solr": "<2.8.3", + "apereo/phpcas": "<1.6", + "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6|>=2.6,<2.7.10|>=3,<3.0.12|>=3.1,<3.1.3", + "appwrite/server-ce": "<=1.2.1", + "arc/web": "<3", + "area17/twill": "<1.2.5|>=2,<2.5.3", + "artesaos/seotools": "<0.17.2", + "asymmetricrypt/asymmetricrypt": "<9.9.99", + "athlon1600/php-proxy": "<=5.1", + "athlon1600/php-proxy-app": "<=3", + "austintoddj/canvas": "<=3.4.2", + "automad/automad": "<=1.10.9", + "awesome-support/awesome-support": "<=6.0.7", + "aws/aws-sdk-php": "<3.288.1", + "azuracast/azuracast": "<0.18.3", + "backdrop/backdrop": "<1.24.2", + "backpack/crud": "<3.4.9", + "bacula-web/bacula-web": "<8.0.0.0-RC2-dev", + "badaso/core": "<2.7", + "bagisto/bagisto": "<2.1", + "barrelstrength/sprout-base-email": "<1.2.7", + "barrelstrength/sprout-forms": "<3.9", + "barryvdh/laravel-translation-manager": "<0.6.2", + "barzahlen/barzahlen-php": "<2.0.1", + "baserproject/basercms": "<5.0.9", + "bassjobsen/bootstrap-3-typeahead": ">4.0.2", + "bigfork/silverstripe-form-capture": ">=3,<3.1.1", + "billz/raspap-webgui": "<2.9.5", + "bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3", + "bmarshall511/wordpress_zero_spam": "<5.2.13", + "bolt/bolt": "<3.7.2", + "bolt/core": "<=4.2", + "bottelet/flarepoint": "<2.2.1", + "bref/bref": "<2.1.13", + "brightlocal/phpwhois": "<=4.2.5", + "brotkrueml/codehighlight": "<2.7", + "brotkrueml/schema": "<1.13.1|>=2,<2.5.1", + "brotkrueml/typo3-matomo-integration": "<1.3.2", + "buddypress/buddypress": "<7.2.1", + "bugsnag/bugsnag-laravel": ">=2,<2.0.2", + "bytefury/crater": "<6.0.2", + "cachethq/cachet": "<2.5.1", + "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", + "cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", + "cardgate/magento2": "<2.0.33", + "cardgate/woocommerce": "<=3.1.15", + "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", + "cartalyst/sentry": "<=2.1.6", + "catfan/medoo": "<1.7.5", + "cecil/cecil": "<7.47.1", + "centreon/centreon": "<22.10.0.0-beta1", + "cesnet/simplesamlphp-module-proxystatistics": "<3.1", + "chriskacerguis/codeigniter-restserver": "<=2.7.1", + "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3", + "ckeditor/ckeditor": "<4.24", + "cockpit-hq/cockpit": "<=2.6.3|==2.7", + "codeception/codeception": "<3.1.3|>=4,<4.1.22", + "codeigniter/framework": "<3.1.9", + "codeigniter4/framework": "<=4.4.2", + "codeigniter4/shield": "<1.0.0.0-beta8", + "codiad/codiad": "<=2.8.4", + "composer/composer": "<1.10.27|>=2,<2.2.23|>=2.3,<2.7", + "concrete5/concrete5": "<9.2.7", + "concrete5/core": "<8.5.8|>=9,<9.1", + "contao-components/mediaelement": ">=2.14.2,<2.21.1", + "contao/contao": ">=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4", + "contao/core": ">=2,<3.5.39", + "contao/core-bundle": ">=3,<3.5.35|>=4,<4.9.42|>=4.10,<4.13.28|>=5,<5.1.10", + "contao/listing-bundle": ">=4,<4.4.8", + "contao/managed-edition": "<=1.5", + "corveda/phpsandbox": "<1.3.5", + "cosenary/instagram": "<=2.3", + "craftcms/cms": "<4.6.2", + "croogo/croogo": "<4", + "cuyz/valinor": "<0.12", + "czproject/git-php": "<4.0.3", + "darylldoyle/safe-svg": "<1.9.10", + "datadog/dd-trace": ">=0.30,<0.30.2", + "datatables/datatables": "<1.10.10", + "david-garcia/phpwhois": "<=4.3.1", + "dbrisinajumi/d2files": "<1", + "dcat/laravel-admin": "<=2.1.3.0-beta", + "derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3", + "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1|>=7,<7.4", + "desperado/xml-bundle": "<=0.1.7", + "directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2", + "doctrine/annotations": "<1.2.7", + "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2", + "doctrine/common": "<2.4.3|>=2.5,<2.5.1", + "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4", + "doctrine/doctrine-bundle": "<1.5.2", + "doctrine/doctrine-module": "<=0.7.1", + "doctrine/mongodb-odm": "<1.0.2", + "doctrine/mongodb-odm-bundle": "<3.0.1", + "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", + "dolibarr/dolibarr": "<18.0.2", + "dompdf/dompdf": "<2.0.4", + "doublethreedigital/guest-entries": "<3.1.2", + "drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.1.8|>=10.2,<10.2.2", + "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4", + "duncanmcclean/guest-entries": "<3.1.2", + "dweeves/magmi": "<=0.7.24", + "ec-cube/ec-cube": "<2.4.4", + "ecodev/newsletter": "<=4", + "ectouch/ectouch": "<=2.7.2", + "elefant/cms": "<2.0.7", + "elgg/elgg": "<3.3.24|>=4,<4.0.5", + "elijaa/phpmemcacheadmin": "<=1.3", + "encore/laravel-admin": "<=1.8.19", + "endroid/qr-code-bundle": "<3.4.2", + "enhavo/enhavo-app": "<=0.13.1", + "enshrined/svg-sanitize": "<0.15", + "erusev/parsedown": "<1.7.2", + "ether/logs": "<3.0.4", + "evolutioncms/evolution": "<=3.2.3", + "exceedone/exment": "<4.4.3|>=5,<5.0.3", + "exceedone/laravel-admin": "<2.2.3|==3", + "ezsystems/demobundle": ">=5.4,<5.4.6.1-dev", + "ezsystems/ez-support-tools": ">=2.2,<2.2.3", + "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1-dev", + "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1-dev|>=5.4,<5.4.11.1-dev|>=2017.12,<2017.12.0.1-dev", + "ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24", + "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26", + "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1", + "ezsystems/ezplatform-graphql": ">=1.0.0.0-RC1-dev,<1.0.13|>=2.0.0.0-beta1,<2.3.12", + "ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.34", + "ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8", + "ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1-dev", + "ezsystems/ezplatform-solr-search-engine": ">=1.7,<1.7.12|>=2,<2.0.2|>=3.3,<3.3.15", + "ezsystems/ezplatform-user": ">=1,<1.0.1", + "ezsystems/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31", + "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.06,<=2019.03.5.1", + "ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3", + "ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15", + "ezyang/htmlpurifier": "<4.1.1", + "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2", + "facturascripts/facturascripts": "<=2022.08", + "feehi/cms": "<=2.1.1", + "feehi/feehicms": "<=2.1.1", + "fenom/fenom": "<=2.12.1", + "filegator/filegator": "<7.8", + "firebase/php-jwt": "<6", + "fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2", + "fixpunkt/fp-newsletter": "<1.1.1|>=2,<2.1.2|>=2.2,<3.2.6", + "flarum/core": "<1.8.5", + "flarum/framework": "<1.8.5", + "flarum/mentions": "<1.6.3", + "flarum/sticky": ">=0.1.0.0-beta14,<=0.1.0.0-beta15", + "flarum/tags": "<=0.1.0.0-beta13", + "floriangaerber/magnesium": "<0.3.1", + "fluidtypo3/vhs": "<5.1.1", + "fof/byobu": ">=0.3.0.0-beta2,<1.1.7", + "fof/upload": "<1.2.3", + "foodcoopshop/foodcoopshop": ">=3.2,<3.6.1", + "fooman/tcpdf": "<6.2.22", + "forkcms/forkcms": "<5.11.1", + "fossar/tcpdf-parser": "<6.2.22", + "francoisjacquet/rosariosis": "<11", + "frappant/frp-form-answers": "<3.1.2|>=4,<4.0.2", + "friendsofsymfony/oauth2-php": "<1.3", + "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", + "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", + "friendsoftypo3/mediace": ">=7.6.2,<7.6.5", + "friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6", + "froala/wysiwyg-editor": "<3.2.7|>=4.0.1,<=4.1.1", + "froxlor/froxlor": "<=2.1.1", + "fuel/core": "<1.8.1", + "funadmin/funadmin": "<=3.2|>=3.3.2,<=3.3.3", + "gaoming13/wechat-php-sdk": "<=1.10.2", + "genix/cms": "<=1.1.11", + "getgrav/grav": "<1.7.44", + "getkirby/cms": "<4.1.1", + "getkirby/kirby": "<=2.5.12", + "getkirby/panel": "<2.5.14", + "getkirby/starterkit": "<=3.7.0.2", + "gilacms/gila": "<=1.15.4", + "gleez/cms": "<=1.2|==2", + "globalpayments/php-sdk": "<2", + "gogentooss/samlbase": "<1.2.7", + "google/protobuf": "<3.15", + "gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3", + "gree/jose": "<2.2.1", + "gregwar/rst": "<1.0.3", + "grumpydictator/firefly-iii": "<6.1.7", + "gugoan/economizzer": "<=0.9.0.0-beta1", + "guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5", + "guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5", + "haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2", + "harvesthq/chosen": "<1.8.7", + "helloxz/imgurl": "<=2.31", + "hhxsv5/laravel-s": "<3.7.36", + "hillelcoren/invoice-ninja": "<5.3.35", + "himiklab/yii2-jqgrid-widget": "<1.0.8", + "hjue/justwriting": "<=1", + "hov/jobfair": "<1.0.13|>=2,<2.0.2", + "httpsoft/http-message": "<1.0.12", + "hyn/multi-tenant": ">=5.6,<5.7.2", + "ibexa/admin-ui": ">=4.2,<4.2.3", + "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.4", + "ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3", + "ibexa/post-install": "<=1.0.4", + "ibexa/solr": ">=4.5,<4.5.4", + "ibexa/user": ">=4,<4.4.3", + "icecoder/icecoder": "<=8.1", + "idno/known": "<=1.3.1", + "illuminate/auth": "<5.5.10", + "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.99999|>=4.2,<=4.2.99999|>=5,<=5.0.99999|>=5.1,<=5.1.99999|>=5.2,<=5.2.99999|>=5.3,<=5.3.99999|>=5.4,<=5.4.99999|>=5.5,<=5.5.49|>=5.6,<=5.6.99999|>=5.7,<=5.7.99999|>=5.8,<=5.8.99999|>=6,<6.18.31|>=7,<7.22.4", + "illuminate/database": "<6.20.26|>=7,<7.30.5|>=8,<8.40", + "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15", + "illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75", + "impresscms/impresscms": "<=1.4.5", + "impresspages/impresspages": "<=1.0.12", + "in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3", + "in2code/ipandlanguageredirect": "<5.1.2", + "in2code/lux": "<17.6.1|>=18,<24.0.2", + "innologi/typo3-appointments": "<2.0.6", + "intelliants/subrion": "<4.2.2", + "islandora/islandora": ">=2,<2.4.1", + "ivankristianto/phpwhois": "<=4.3", + "jackalope/jackalope-doctrine-dbal": "<1.7.4", + "james-heinrich/getid3": "<1.9.21", + "james-heinrich/phpthumb": "<1.7.12", + "jasig/phpcas": "<1.3.3", + "jcbrand/converse.js": "<3.3.3", + "joomla/application": "<1.0.13", + "joomla/archive": "<1.1.12|>=2,<2.0.1", + "joomla/filesystem": "<1.6.2|>=2,<2.0.1", + "joomla/filter": "<1.4.4|>=2,<2.0.1", + "joomla/framework": "<1.5.7|>=2.5.4,<=3.8.12", + "joomla/input": ">=2,<2.0.2", + "joomla/joomla-cms": ">=2.5,<3.9.12", + "joomla/session": "<1.3.1", + "joyqi/hyper-down": "<=2.4.27", + "jsdecena/laracom": "<2.0.9", + "jsmitty12/phpwhois": "<5.1", + "juzaweb/cms": "<=3.4", + "kazist/phpwhois": "<=4.2.6", + "kelvinmo/simplexrd": "<3.1.1", + "kevinpapst/kimai2": "<1.16.7", + "khodakhah/nodcms": "<=3", + "kimai/kimai": "<2.1", + "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", + "klaviyo/magento2-extension": ">=1,<3", + "knplabs/knp-snappy": "<=1.4.2", + "kohana/core": "<3.3.3", + "krayin/laravel-crm": "<1.2.2", + "kreait/firebase-php": ">=3.2,<3.8.1", + "la-haute-societe/tcpdf": "<6.2.22", + "laminas/laminas-diactoros": "<2.18.1|==2.19|==2.20|==2.21|==2.22|==2.23|>=2.24,<2.24.2|>=2.25,<2.25.2", + "laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1", + "laminas/laminas-http": "<2.14.2", + "laravel/fortify": "<1.11.1", + "laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75", + "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", + "latte/latte": "<2.10.8", + "lavalite/cms": "<=9", + "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5", + "league/commonmark": "<0.18.3", + "league/flysystem": "<1.1.4|>=2,<2.1.1", + "league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3", + "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", + "librenms/librenms": "<2017.08.18", + "liftkit/database": "<2.13.2", + "limesurvey/limesurvey": "<3.27.19", + "livehelperchat/livehelperchat": "<=3.91", + "livewire/livewire": ">2.2.4,<2.2.6", + "lms/routes": "<2.1.1", + "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2", + "luyadev/yii-helpers": "<1.2.1", + "magento/community-edition": "<2.4.3.0-patch3|>=2.4.4,<2.4.5", + "magento/core": "<=1.9.4.5", + "magento/magento1ce": "<1.9.4.3-dev", + "magento/magento1ee": ">=1,<1.14.4.3-dev", + "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2.0-patch2", + "magneto/core": "<1.9.4.4-dev", + "maikuolan/phpmussel": ">=1,<1.6", + "mainwp/mainwp": "<=4.4.3.3", + "mantisbt/mantisbt": "<2.26.1", + "marcwillmann/turn": "<0.3.3", + "matyhtf/framework": "<3.0.6", + "mautic/core": "<4.3", + "mediawiki/core": "<1.36.2", + "mediawiki/matomo": "<2.4.3", + "mediawiki/semantic-media-wiki": "<4.0.2", + "melisplatform/melis-asset-manager": "<5.0.1", + "melisplatform/melis-cms": "<5.0.1", + "melisplatform/melis-front": "<5.0.1", + "mezzio/mezzio-swoole": "<3.7|>=4,<4.3", + "mgallegos/laravel-jqgrid": "<=1.3", + "microsoft/microsoft-graph": ">=1.16,<1.109.1|>=2,<2.0.1", + "microsoft/microsoft-graph-beta": "<2.0.1", + "microsoft/microsoft-graph-core": "<2.0.2", + "microweber/microweber": "<=2.0.4", + "miniorange/miniorange-saml": "<1.4.3", + "mittwald/typo3_forum": "<1.2.1", + "mobiledetect/mobiledetectlib": "<2.8.32", + "modx/revolution": "<=2.8.3.0-patch", + "mojo42/jirafeau": "<4.4", + "mongodb/mongodb": ">=1,<1.9.2", + "monolog/monolog": ">=1.8,<1.12", + "moodle/moodle": "<4.3.3", + "mos/cimage": "<0.7.19", + "movim/moxl": ">=0.8,<=0.10", + "mpdf/mpdf": "<=7.1.7", + "munkireport/comment": "<4.1", + "munkireport/managedinstalls": "<2.6", + "munkireport/munkireport": ">=2.5.3,<5.6.3", + "mustache/mustache": ">=2,<2.14.1", + "namshi/jose": "<2.2", + "neoan3-apps/template": "<1.1.1", + "neorazorx/facturascripts": "<2022.04", + "neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", + "neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3", + "neos/media-browser": "<7.3.19|>=8,<8.0.16|>=8.1,<8.1.11|>=8.2,<8.2.11|>=8.3,<8.3.9", + "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.9.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2", + "neos/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", + "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", + "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", + "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", + "nilsteampassnet/teampass": "<3.0.10", + "nonfiction/nterchange": "<4.1.1", + "notrinos/notrinos-erp": "<=0.7", + "noumo/easyii": "<=0.9", + "nukeviet/nukeviet": "<4.5.02", + "nyholm/psr7": "<1.6.1", + "nystudio107/craft-seomatic": "<3.4.12", + "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1", + "october/backend": "<1.1.2", + "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1", + "october/october": "<=3.4.4", + "october/rain": "<1.0.472|>=1.1,<1.1.2", + "october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.5.2", + "omeka/omeka-s": "<4.0.3", + "onelogin/php-saml": "<2.10.4", + "oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5", + "open-web-analytics/open-web-analytics": "<1.7.4", + "opencart/opencart": "<=3.0.3.7|>=4,<4.0.2.3-dev", + "openid/php-openid": "<2.3", + "openmage/magento-lts": "<20.5", + "opensource-workshop/connect-cms": "<1.7.2|>=2,<2.3.2", + "orchid/platform": ">=9,<9.4.4|>=14.0.0.0-alpha4,<14.5", + "oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1", + "oro/commerce": ">=4.1,<5.0.11|>=5.1,<5.1.1", + "oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7", + "oro/crm-call-bundle": ">=4.2,<=4.2.5|>=5,<5.0.4|>=5.1,<5.1.1", + "oro/customer-portal": ">=4.2,<=4.2.8|>=5,<5.0.11|>=5.1,<5.1.1", + "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<=4.2.10|>=5,<5.0.8", + "oxid-esales/oxideshop-ce": "<4.5", + "packbackbooks/lti-1-3-php-library": "<5", + "padraic/humbug_get_contents": "<1.1.2", + "pagarme/pagarme-php": "<3", + "pagekit/pagekit": "<=1.0.18", + "paragonie/random_compat": "<2", + "passbolt/passbolt_api": "<2.11", + "paypal/merchant-sdk-php": "<3.12", + "pear/archive_tar": "<1.4.14", + "pear/auth": "<1.2.4", + "pear/crypt_gpg": "<1.6.7", + "pear/pear": "<=1.10.1", + "pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1", + "personnummer/personnummer": "<3.0.2", + "phanan/koel": "<5.1.4", + "phenx/php-svg-lib": "<0.5.2", + "php-mod/curl": "<2.3.2", + "phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1", + "phpems/phpems": ">=6,<=6.1.3", + "phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7", + "phpmailer/phpmailer": "<6.5", + "phpmussel/phpmussel": ">=1,<1.6", + "phpmyadmin/phpmyadmin": "<5.2.1", + "phpmyfaq/phpmyfaq": "<3.2.5", + "phpoffice/phpexcel": "<1.8", + "phpoffice/phpspreadsheet": "<1.16", + "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36", + "phpservermon/phpservermon": "<3.6", + "phpsysinfo/phpsysinfo": "<3.4.3", + "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", + "phpwhois/phpwhois": "<=4.2.5", + "phpxmlrpc/extras": "<0.6.1", + "phpxmlrpc/phpxmlrpc": "<4.9.2", + "pi/pi": "<=2.5", + "pimcore/admin-ui-classic-bundle": "<1.3.4", + "pimcore/customer-management-framework-bundle": "<4.0.6", + "pimcore/data-hub": "<1.2.4", + "pimcore/demo": "<10.3", + "pimcore/ecommerce-framework-bundle": "<1.0.10", + "pimcore/perspective-editor": "<1.5.1", + "pimcore/pimcore": "<11.1.1", + "pixelfed/pixelfed": "<0.11.11", + "plotly/plotly.js": "<2.25.2", + "pocketmine/bedrock-protocol": "<8.0.2", + "pocketmine/pocketmine-mp": "<5.11.2", + "pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1", + "pressbooks/pressbooks": "<5.18", + "prestashop/autoupgrade": ">=4,<4.10.1", + "prestashop/blockreassurance": "<=5.1.3", + "prestashop/blockwishlist": ">=2,<2.1.1", + "prestashop/contactform": ">=1.0.1,<4.3", + "prestashop/gamification": "<2.3.2", + "prestashop/prestashop": "<8.1.4", + "prestashop/productcomments": "<5.0.2", + "prestashop/ps_emailsubscription": "<2.6.1", + "prestashop/ps_facetedsearch": "<3.4.1", + "prestashop/ps_linklist": "<3.1", + "privatebin/privatebin": "<1.4", + "processwire/processwire": "<=3.0.210", + "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7", + "propel/propel1": ">=1,<=1.7.1", + "pterodactyl/panel": "<1.7", + "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2", + "ptrofimov/beanstalk_console": "<1.7.14", + "pubnub/pubnub": "<6.1", + "pusher/pusher-php-server": "<2.2.1", + "pwweb/laravel-core": "<=0.3.6.0-beta", + "pyrocms/pyrocms": "<=3.9.1", + "rainlab/blog-plugin": "<1.4.1", + "rainlab/debugbar-plugin": "<3.1", + "rainlab/user-plugin": "<=1.4.5", + "rankmath/seo-by-rank-math": "<=1.0.95", + "rap2hpoutre/laravel-log-viewer": "<0.13", + "react/http": ">=0.7,<1.9", + "really-simple-plugins/complianz-gdpr": "<6.4.2", + "redaxo/source": "<=5.15.1", + "remdex/livehelperchat": "<4.29", + "reportico-web/reportico": "<=7.1.21", + "rhukster/dom-sanitizer": "<1.0.7", + "rmccue/requests": ">=1.6,<1.8", + "robrichards/xmlseclibs": ">=1,<3.0.4", + "roots/soil": "<4.1", + "rudloff/alltube": "<3.0.3", + "s-cart/core": "<6.9", + "s-cart/s-cart": "<6.9", + "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1", + "sabre/dav": ">=1.6,<1.7.11|>=1.8,<1.8.9", + "scheb/two-factor-bundle": "<3.26|>=4,<4.11", + "sensiolabs/connect": "<4.2.3", + "serluck/phpwhois": "<=4.2.6", + "sfroemken/url_redirect": "<=1.2.1", + "sheng/yiicms": "<=1.2", + "shopware/core": "<=6.5.7.3", + "shopware/platform": "<=6.5.7.3|>=6.5.8,<6.5.8.7-dev", + "shopware/production": "<=6.3.5.2", + "shopware/shopware": "<=5.7.17", + "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev", + "shopxo/shopxo": "<2.2.6", + "showdoc/showdoc": "<2.10.4", + "silverstripe-australia/advancedreports": ">=1,<=2", + "silverstripe/admin": "<1.13.19|>=2,<2.1.8", + "silverstripe/assets": ">=1,<1.11.1", + "silverstripe/cms": "<4.11.3", + "silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1", + "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", + "silverstripe/framework": "<4.13.39|>=5,<5.1.11", + "silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3", + "silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1", + "silverstripe/recipe-cms": ">=4.5,<4.5.3", + "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1", + "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4", + "silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1", + "silverstripe/subsites": ">=2,<2.6.1", + "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1", + "silverstripe/userforms": "<3", + "silverstripe/versioned-admin": ">=1,<1.11.1", + "simple-updates/phpwhois": "<=1", + "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4|==5.0.0.0-alpha12", + "simplesamlphp/simplesamlphp": "<1.18.6", + "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", + "simplesamlphp/simplesamlphp-module-openid": "<1", + "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9", + "simplesamlphp/xml-security": "==1.6.11", + "simplito/elliptic-php": "<1.0.6", + "sitegeist/fluid-components": "<3.5", + "sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3", + "slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1", + "slim/slim": "<2.6", + "slub/slub-events": "<3.0.3", + "smarty/smarty": "<3.1.48|>=4,<4.3.1", + "snipe/snipe-it": "<=6.2.2", + "socalnick/scn-social-auth": "<1.15.2", + "socialiteproviders/steam": "<1.1", + "spatie/browsershot": "<3.57.4", + "spipu/html2pdf": "<5.2.8", + "spoon/library": "<1.4.1", + "spoonity/tcpdf": "<6.2.22", + "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", + "ssddanbrown/bookstack": "<22.02.3", + "statamic/cms": "<4.46", + "stormpath/sdk": "<9.9.99", + "studio-42/elfinder": "<2.1.62", + "subhh/libconnect": "<7.0.8|>=8,<8.1", + "sukohi/surpass": "<1", + "sulu/sulu": "<1.6.44|>=2,<2.4.17|>=2.5,<2.5.13", + "sumocoders/framework-user-bundle": "<1.4", + "superbig/craft-audit": "<3.0.2", + "swag/paypal": "<5.4.4", + "swiftmailer/swiftmailer": ">=4,<5.4.5", + "swiftyedit/swiftyedit": "<1.2", + "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", + "sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", + "sylius/grid-bundle": "<1.10.1", + "sylius/paypal-plugin": ">=1,<1.2.4|>=1.3,<1.3.1", + "sylius/resource-bundle": ">=1,<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4", + "sylius/sylius": "<1.9.10|>=1.10,<1.10.11|>=1.11,<1.11.2", + "symbiote/silverstripe-multivaluefield": ">=3,<3.0.99", + "symbiote/silverstripe-queuedjobs": ">=3,<3.0.2|>=3.1,<3.1.4|>=4,<4.0.7|>=4.1,<4.1.2|>=4.2,<4.2.4|>=4.3,<4.3.3|>=4.4,<4.4.3|>=4.5,<4.5.1|>=4.6,<4.6.4", + "symbiote/silverstripe-seed": "<6.0.3", + "symbiote/silverstripe-versionedfiles": "<=2.0.3", + "symfont/process": ">=0", + "symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", + "symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4", + "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", + "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<5.3.15|>=5.4.3,<5.4.4|>=6.0.3,<6.0.4", + "symfony/http-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7", + "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", + "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1", + "symfony/mime": ">=4.3,<4.3.8", + "symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "symfony/polyfill": ">=1,<1.10", + "symfony/polyfill-php55": ">=1,<1.10", + "symfony/proxy-manager-bridge": ">=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "symfony/routing": ">=2,<2.0.19", + "symfony/security": ">=2,<2.7.51|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.8", + "symfony/security-bundle": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", + "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9", + "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", + "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8", + "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.3.2|>=5.4,<5.4.31|>=6,<6.3.8", + "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", + "symfony/symfony": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", + "symfony/translation": ">=2,<2.0.17", + "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", + "symfony/ux-autocomplete": "<2.11.2", + "symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3", + "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8", + "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", + "symfony/webhook": ">=6.3,<6.3.8", + "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7|>=2.2.0.0-beta1,<2.2.0.0-beta2", + "symphonycms/symphony-2": "<2.6.4", + "t3/dce": "<0.11.5|>=2.2,<2.6.2", + "t3g/svg-sanitizer": "<1.0.3", + "t3s/content-consent": "<1.0.3|>=2,<2.0.2", + "tastyigniter/tastyigniter": "<3.3", + "tcg/voyager": "<=1.4", + "tecnickcom/tcpdf": "<6.2.22", + "terminal42/contao-tablelookupwizard": "<3.3.5", + "thelia/backoffice-default-template": ">=2.1,<2.1.2", + "thelia/thelia": ">=2.1,<2.1.3", + "theonedemon/phpwhois": "<=4.2.5", + "thinkcmf/thinkcmf": "<=5.1.7", + "thorsten/phpmyfaq": "<3.2.2", + "tikiwiki/tiki-manager": "<=17.1", + "tinymce/tinymce": "<5.10.9|>=6,<6.7.3", + "tinymighty/wiki-seo": "<1.2.2", + "titon/framework": "<9.9.99", + "tobiasbg/tablepress": "<=2.0.0.0-RC1", + "topthink/framework": "<6.0.14", + "topthink/think": "<=6.1.1", + "topthink/thinkphp": "<=3.2.3", + "torrentpier/torrentpier": "<=2.4.1", + "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2", + "tribalsystems/zenario": "<=9.4.59197", + "truckersmp/phpwhois": "<=4.3.1", + "ttskch/pagination-service-provider": "<1", + "twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3", + "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", + "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", + "typo3/cms-core": "<=8.7.56|>=9,<=9.5.45|>=10,<=10.4.42|>=11,<=11.5.34|>=12,<=12.4.10|==13", + "typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1", + "typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1", + "typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", + "typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5", + "typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8", + "typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30", + "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", + "typo3/html-sanitizer": ">=1,<=1.5.2|>=2,<=2.1.3", + "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3", + "typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1", + "typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", + "typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10", + "ua-parser/uap-php": "<3.8", + "uasoft-indonesia/badaso": "<=2.9.7", + "unisharp/laravel-filemanager": "<2.6.4", + "userfrosting/userfrosting": ">=0.3.1,<4.6.3", + "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", + "uvdesk/community-skeleton": "<=1.1.1", + "vanilla/safecurl": "<0.9.2", + "verot/class.upload.php": "<=2.1.6", + "vova07/yii2-fileapi-widget": "<0.1.9", + "vrana/adminer": "<4.8.1", + "waldhacker/hcaptcha": "<2.1.2", + "wallabag/tcpdf": "<6.2.22", + "wallabag/wallabag": "<2.6.7", + "wanglelecc/laracms": "<=1.0.3", + "web-auth/webauthn-framework": ">=3.3,<3.3.4", + "webbuilders-group/silverstripe-kapost-bridge": "<0.4", + "webcoast/deferred-image-processing": "<1.0.2", + "webklex/laravel-imap": "<5.3", + "webklex/php-imap": "<5.3", + "webpa/webpa": "<3.1.2", + "wikibase/wikibase": "<=1.39.3", + "wikimedia/parsoid": "<0.12.2", + "willdurand/js-translation-bundle": "<2.1.1", + "winter/wn-backend-module": "<1.2.4", + "winter/wn-system-module": "<1.2.4", + "wintercms/winter": "<1.2.3", + "woocommerce/woocommerce": "<6.6", + "wp-cli/wp-cli": ">=0.12,<2.5", + "wp-graphql/wp-graphql": "<=1.14.5", + "wpanel/wpanel4-cms": "<=4.3.1", + "wpcloud/wp-stateless": "<3.2", + "wwbn/avideo": "<=12.4", + "xataface/xataface": "<3", + "xpressengine/xpressengine": "<3.0.15", + "yeswiki/yeswiki": "<4.1", + "yetiforce/yetiforce-crm": "<=6.4", + "yidashi/yii2cmf": "<=2", + "yii2mod/yii2-cms": "<1.9.2", + "yiisoft/yii": "<1.1.29", + "yiisoft/yii2": "<2.0.38", + "yiisoft/yii2-authclient": "<2.2.15", + "yiisoft/yii2-bootstrap": "<2.0.4", + "yiisoft/yii2-dev": "<2.0.43", + "yiisoft/yii2-elasticsearch": "<2.0.5", + "yiisoft/yii2-gii": "<=2.2.4", + "yiisoft/yii2-jui": "<2.0.4", + "yiisoft/yii2-redis": "<2.0.8", + "yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6", + "yoast-seo-for-typo3/yoast_seo": "<7.2.3", + "yourls/yourls": "<=1.8.2", + "yuan1994/tpadmin": "<=1.3.12", + "zencart/zencart": "<=1.5.7.0-beta", + "zendesk/zendesk_api_client_php": "<2.2.11", + "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", + "zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2", + "zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2", + "zendframework/zend-db": "<2.2.10|>=2.3,<2.3.5", + "zendframework/zend-developer-tools": ">=1.2.2,<1.2.3", + "zendframework/zend-diactoros": "<1.8.4", + "zendframework/zend-feed": "<2.10.3", + "zendframework/zend-form": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-http": "<2.8.1", + "zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6", + "zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3", + "zendframework/zend-mail": ">=2,<2.4.11|>=2.5,<2.7.2", + "zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-session": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.9|>=2.3,<2.3.4", + "zendframework/zend-validator": ">=2.3,<2.3.6", + "zendframework/zend-view": ">=2,<2.2.7|>=2.3,<2.3.1", + "zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6", + "zendframework/zendframework": "<=3", + "zendframework/zendframework1": "<1.12.20", + "zendframework/zendopenid": "<2.0.2", + "zendframework/zendrest": "<2.0.2", + "zendframework/zendservice-amazon": "<2.0.3", + "zendframework/zendservice-api": "<1", + "zendframework/zendservice-audioscrobbler": "<2.0.2", + "zendframework/zendservice-nirvanix": "<2.0.2", + "zendframework/zendservice-slideshare": "<2.0.2", + "zendframework/zendservice-technorati": "<2.0.2", + "zendframework/zendservice-windowsazure": "<2.0.2", + "zendframework/zendxml": ">=1,<1.0.1", + "zenstruck/collection": "<0.2.1", + "zetacomponents/mail": "<1.8.2", + "zf-commons/zfc-user": "<1.2.2", + "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3", + "zfr/zfr-oauth2-server-module": "<0.1.2", + "zoujingli/thinkadmin": "<=6.1.53" + }, + "default-branch": true, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "role": "maintainer" + }, + { + "name": "Ilya Tribusean", + "email": "slash3b@gmail.com", + "role": "maintainer" + } + ], + "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", + "keywords": [ + "dev" + ], + "support": { + "issues": "https://github.com/Roave/SecurityAdvisories/issues", + "source": "https://github.com/Roave/SecurityAdvisories/tree/latest" + }, + "funding": [ + { + "url": "https://github.com/Ocramius", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/roave/security-advisories", + "type": "tidelift" + } + ], + "time": "2024-03-08T12:05:25+00:00" + }, + { + "name": "sabre/event", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/event.git", + "reference": "d7da22897125d34d7eddf7977758191c06a74497" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/event/zipball/d7da22897125d34d7eddf7977758191c06a74497", + "reference": "d7da22897125d34d7eddf7977758191c06a74497", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + }, + "type": "library", + "autoload": { + "files": [ + "lib/coroutine.php", + "lib/Loop/functions.php", + "lib/Promise/functions.php" + ], + "psr-4": { + "Sabre\\Event\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "async", + "coroutine", + "eventloop", + "events", + "hooks", + "plugin", + "promise", + "reactor", + "signal" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/event/issues", + "source": "https://github.com/fruux/sabre-event" + }, + "time": "2021-11-04T06:51:17+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:27:43+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:19:30+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:30:58+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:03:51+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "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", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:33:00+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:35:11+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:20:34+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:07:39+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:13:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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 that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "spatie/array-to-xml", + "version": "3.2.3", + "source": { + "type": "git", + "url": "https://github.com/spatie/array-to-xml.git", + "reference": "c95fd4db94ec199f798d4b5b4a81757bd20d88ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/c95fd4db94ec199f798d4b5b4a81757bd20d88ab", + "reference": "c95fd4db94ec199f798d4b5b4a81757bd20d88ab", + "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", + "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.2.3" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-02-07T10:39:02+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.9.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b", + "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b", + "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" + } + ], + "time": "2024-02-16T15:06:51+00:00" + }, + { + "name": "symfony/config", + "version": "v6.4.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "6ea4affc27f2086c9d16b92ab5429ce1e3c38047" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/6ea4affc27f2086c9d16b92ab5429ce1e3c38047", + "reference": "6ea4affc27f2086c9d16b92ab5429ce1e3c38047", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "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": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v6.4.4" + }, + "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-02-26T07:52:26+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v6.4.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "6236e5e843cb763e9d0f74245678b994afea5363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6236e5e843cb763e9d0f74245678b994afea5363", + "reference": "6236e5e843cb763e9d0f74245678b994afea5363", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.2.10|^7.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<6.1", + "symfony/finder": "<5.4", + "symfony/proxy-manager-bridge": "<6.3", + "symfony/yaml": "<5.4" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^6.1|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "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": "Allows you to standardize and centralize the way objects are constructed in your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.4" + }, + "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-02-22T20:27:10+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "ae9d3a6f3003a6caf56acd7466d8d52378d44fef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ae9d3a6f3003a6caf56acd7466d8d52378d44fef", + "reference": "ae9d3a6f3003a6caf56acd7466d8d52378d44fef", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.3" + }, + "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-01-23T14:51:35+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.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": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", + "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "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/v6.4.3" + }, + "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-01-23T14:51:35+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", + "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.4.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": "2023-10-31T17:30:12+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "22301f0e7fdeaacc14318928612dee79be99860e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/22301f0e7fdeaacc14318928612dee79be99860e", + "reference": "22301f0e7fdeaacc14318928612dee79be99860e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v6.4.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": "2023-08-08T10:16:24+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.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-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", + "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "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.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.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-01-29T20:11:03+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "416596166641f1f728b0a64f5b9dd07cceb410c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/416596166641f1f728b0a64f5b9dd07cceb410c1", + "reference": "416596166641f1f728b0a64f5b9dd07cceb410c1", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "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 a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v6.4.3" + }, + "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-01-23T14:35:58+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v6.4.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "b439823f04c98b84d4366c79507e9da6230944b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b439823f04c98b84d4366c79507e9da6230944b1", + "reference": "b439823f04c98b84d4366c79507e9da6230944b1", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^6.3|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", + "twig/twig": "^2.13|^3.0.4" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "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 mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v6.4.4" + }, + "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-02-15T11:23:52+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v6.4.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "0bd342e24aef49fc82a21bd4eedd3e665d177e5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/0bd342e24aef49fc82a21bd4eedd3e665d177e5b", + "reference": "0bd342e24aef49fc82a21bd4eedd3e665d177e5b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "require-dev": { + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "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": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v6.4.4" + }, + "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-02-26T08:37:45+00:00" + }, + { + "name": "symfony/yaml", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "d75715985f0f94f978e3a8fa42533e10db921b90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/d75715985f0f94f978e3a8fa42533e10db921b90", + "reference": "d75715985f0f94f978e3a8fa42533e10db921b90", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "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": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v6.4.3" + }, + "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-01-23T14:51:35+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": "tysonandre/var_representation_polyfill", + "version": "0.1.3", + "source": { + "type": "git", + "url": "https://github.com/TysonAndre/var_representation_polyfill.git", + "reference": "e9116c2c352bb0835ca428b442dde7767c11ad32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TysonAndre/var_representation_polyfill/zipball/e9116c2c352bb0835ca428b442dde7767c11ad32", + "reference": "e9116c2c352bb0835ca428b442dde7767c11ad32", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.2.0|^8.0.0" + }, + "provide": { + "ext-var_representation": "*" + }, + "require-dev": { + "phan/phan": "^5.4.1", + "phpunit/phpunit": "^8.5.0" + }, + "suggest": { + "ext-var_representation": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.3-dev" + } + }, + "autoload": { + "files": [ + "src/var_representation.php" + ], + "psr-4": { + "VarRepresentation\\": "src/VarRepresentation" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + } + ], + "description": "Polyfill for var_representation: convert a variable to a string in a way that fixes the shortcomings of var_export", + "keywords": [ + "var_export", + "var_representation" + ], + "support": { + "issues": "https://github.com/TysonAndre/var_representation_polyfill/issues", + "source": "https://github.com/TysonAndre/var_representation_polyfill/tree/0.1.3" + }, + "time": "2022-08-31T12:59:22+00:00" + }, + { + "name": "ulrichsg/getopt-php", + "version": "v4.0.3", + "source": { + "type": "git", + "url": "https://github.com/getopt-php/getopt-php.git", + "reference": "91c31c9bc0ff9bbe22b0b02c63c7f5ddb8d2a8d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getopt-php/getopt-php/zipball/91c31c9bc0ff9bbe22b0b02c63c7f5ddb8d2a8d5", + "reference": "91c31c9bc0ff9bbe22b0b02c63c7f5ddb8d2a8d5", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "*", + "squizlabs/php_codesniffer": "^3.5.8", + "tflori/phpunit-printer": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "GetOpt\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ulrich Schmidt-Goertz", + "email": "ulrich@schmidt-goertz.de" + }, + { + "name": "Thomas Flori", + "email": "thflori@gmail.com" + } + ], + "description": "Command line arguments parser for PHP 7.1 and above", + "homepage": "http://getopt-php.github.io/getopt-php", + "support": { + "issues": "https://github.com/getopt-php/getopt-php/issues", + "source": "https://github.com/getopt-php/getopt-php/tree/v4.0.3" + }, + "time": "2022-12-13T20:37:45+00:00" + }, + { + "name": "vimeo/psalm", + "version": "5.22.2", + "source": { + "type": "git", + "url": "https://github.com/vimeo/psalm.git", + "reference": "d768d914152dbbf3486c36398802f74e80cfde48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/d768d914152dbbf3486c36398802f74e80cfde48", + "reference": "d768d914152dbbf3486c36398802f74e80cfde48", + "shasum": "" + }, + "require": { + "amphp/amp": "^2.4.2", + "amphp/byte-stream": "^1.5", + "composer-runtime-api": "^2", + "composer/semver": "^1.4 || ^2.0 || ^3.0", + "composer/xdebug-handler": "^2.0 || ^3.0", + "dnoegel/php-xdg-base-dir": "^0.1.1", + "ext-ctype": "*", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.1", + "felixfbecker/language-server-protocol": "^1.5.2", + "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0", + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "nikic/php-parser": "^4.16", + "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "spatie/array-to-xml": "^2.17.0 || ^3.0", + "symfony/console": "^4.1.6 || ^5.0 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0" + }, + "conflict": { + "nikic/php-parser": "4.17.0" + }, + "provide": { + "psalm/psalm": "self.version" + }, + "require-dev": { + "amphp/phpunit-util": "^2.0", + "bamarni/composer-bin-plugin": "^1.4", + "brianium/paratest": "^6.9", + "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.18", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.6", + "symfony/process": "^4.4 || ^5.0 || ^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", + "psalter" + ], + "type": "project", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev", + "dev-4.x": "4.x-dev", + "dev-3.x": "3.x-dev", + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psalm\\": "src/Psalm/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Brown" + } + ], + "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": "2024-02-22T23:39:07+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": { + "roave/security-advisories": 20 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^8.1", + "ext-mbstring": "*" + }, + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/csv-blueprint b/csv-blueprint new file mode 100644 index 00000000..c98a086a --- /dev/null +++ b/csv-blueprint @@ -0,0 +1,43 @@ +#!/usr/bin/env php +registerCommandsByPath(PATH_ROOT . '/src/Commands', __NAMESPACE__) + ->setLogo( + <<<'EOF' + _____ ______ _ _ _ + / __ \ | ___ \ | (_) | | + | / \/_____ __ | |_/ / |_ _ ___ _ __ _ __ _ _ __ | |_ + | | / __\ \ / / | ___ \ | | | |/ _ \ '_ \| '__| | '_ \| __| + | \__/\__ \\ V / | |_/ / | |_| | __/ |_) | | | | | | | |_ + \____/___/ \_/ \____/|_|\__,_|\___| .__/|_| |_|_| |_|\__| + | | + |_| + EOF, + ) + ->run(); diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..9ca3124e --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,53 @@ + + + + + + src + + + + + + + + + + + + tests + + + + + + + diff --git a/schema-examples/full.json b/schema-examples/full.json new file mode 100644 index 00000000..51bf4158 --- /dev/null +++ b/schema-examples/full.json @@ -0,0 +1,46 @@ +{ + "csv" : { + "header" : true, + "delimiter" : ",", + "quote_char" : "\\", + "enclosure" : "\"", + "encoding" : "utf-8", + "bom" : false + }, + "columns" : [ + { + "name" : "csv_header_name", + "description" : "Lorem ipsum", + "rules" : { + "not_empty" : true, + "exact_value" : "Some string", + "allow_values" : ["y", "n", ""], + "regex" : "\/^[\\d]{2}$\/", + "min_length" : 1, + "max_length" : 10, + "only_trimed" : true, + "only_lowercase" : true, + "only_uppercase" : true, + "only_capitalize" : true, + "min" : 10, + "max" : 100.5, + "precision" : 2, + "date_format" : "Y-m-d", + "min_date" : "2000-01-02", + "max_date" : "+1 day", + "is_bool" : true, + "is_int" : true, + "is_float" : true, + "is_ip" : true, + "is_url" : true, + "is_email" : true, + "is_domain" : true, + "is_uuid4" : true, + "is_latitude" : true, + "is_longitude" : true, + "cardinal_direction" : true, + "usa_market_name" : true + } + } + ] +} diff --git a/schema-examples/full.php b/schema-examples/full.php new file mode 100644 index 00000000..b5bae14a --- /dev/null +++ b/schema-examples/full.php @@ -0,0 +1,62 @@ + [ + 'header' => true, + 'delimiter' => ',', + 'quote_char' => '\\', + 'enclosure' => '"', + 'encoding' => 'utf-8', + 'bom' => false, + ], + 'columns' => [ + [ + 'name' => 'csv_header_name', + 'description' => 'Lorem ipsum', + 'rules' => [ + 'not_empty' => true, + 'exact_value' => 'Some string', + 'allow_values' => ['y', 'n', ''], + 'regex' => '/^[\\d]{2}$/', + 'min_length' => 1, + 'max_length' => 10, + 'only_trimed' => true, + 'only_lowercase' => true, + 'only_uppercase' => true, + 'only_capitalize' => true, + 'min' => 10, + 'max' => 100.5, + 'precision' => 2, + 'date_format' => 'Y-m-d', + 'min_date' => '2000-01-02', + 'max_date' => '+1 day', + 'is_bool' => true, + 'is_int' => true, + 'is_float' => true, + 'is_ip' => true, + 'is_url' => true, + 'is_email' => true, + 'is_domain' => true, + 'is_uuid4' => true, + 'is_latitude' => true, + 'is_longitude' => true, + 'cardinal_direction' => true, + 'usa_market_name' => true, + ], + ], + ], +]; diff --git a/schema-examples/full.yml b/schema-examples/full.yml new file mode 100644 index 00000000..b49102eb --- /dev/null +++ b/schema-examples/full.yml @@ -0,0 +1,68 @@ +# +# JBZoo Toolbox - Csv-Blueprint. +# +# This file is part of the JBZoo Toolbox project. +# For the full copyright and license information, please view the LICENSE +# file that was distributed with this source code. +# +# @license MIT +# @copyright Copyright (C) JBZoo.com, All rights reserved. +# @see https://github.com/JBZoo/Csv-Blueprint +# + +# It's a full example of the CSV schema file in YAML format. + +csv: # Here are default values. You can skip this section if you don't need to override the default values + header: true # If the first row is a header. If true, name of each column is required + delimiter: , # Delimiter character in CSV file + quote_char: \ # Quote character in CSV file + enclosure: "\"" # Enclosure for each field in CSV file + encoding: utf-8 # Only utf-8, utf-16, utf-32 (Experimental) + bom: false # If the file has a BOM (Byte Order Mark) at the beginning (Experimental) + +columns: + - name: "csv_header_name" # Any custom name of the column in the CSV file (first row). Required if "csv_structure.header" is true. + description: "Lorem ipsum" # Optional. Description of the column. Not used in the validation process. + rules: + # You can use the rules in any combination. Or not use any of them. + # They are grouped below simply for ease of navigation and reading. + # If you see the value for the rule is "true" - that's just an enable flag. + # In other cases, these are rule parameters. + + # General rules + not_empty: true # Value is not empty string. Ignore spaces. + exact_value: Some string # Case-sensitive. Exact value for string in the column + allow_values: [ y, n, "" ] # Strict set of values that are allowed. Case-sensitive. + + # Strings only + regex: /^[\d]{2}$/ # Any valid regex pattern. See https://www.php.net/manual/en/reference.pcre.pattern.syntax.php + min_length: 1 # Integer only. Min length of the string with spaces + max_length: 10 # Integer only. Max length of the string with spaces + only_trimed: true # Only trimed strings. Example: "Hello World" (not " Hello World ") + only_lowercase: true # String is only lower-case. Example: "hello world" + only_uppercase: true # String is only upper-case. Example: "HELLO WORLD" + only_capitalize: true # String is only capitalized. Example: "Hello World" + + # Deciaml and integer numbers + min: 10 # Can be integer or float, negative and positive + max: 100.50 # Can be integer or float, negative and positive + precision: 2 # Strict(!) number of digits after the decimal point + + # Dates + date_format: Y-m-d # See: https://www.php.net/manual/en/datetime.format.php + min_date: "2000-01-02" # See examples https://www.php.net/manual/en/function.strtotime.php + max_date: "+1 day" # See examples https://www.php.net/manual/en/function.strtotime.php + + # Specific formats + is_bool: true # Allow only boolean values "true" and "false", case-insensitive + is_int: true # Check format only. Can be negative and positive. Without any separators + is_float: true # Check format only. Can be negative and positive. Dot as decimal separator + is_ip: true # Only IPv4. Example: "127.0.0.1" + is_url: true # Only URL format. Example: "https://example.com/page?query=string#anchor" + is_email: true # Only email format. Example: "user@example.com" + is_domain: true # Only domain name. Example: "example.com" + is_uuid4: true # Only UUID4 format. Example: "550e8400-e29b-41d4-a716-446655440000" + is_latitude: true # Can be integer or float. Example: 50.123456 + is_longitude: true # Can be integer or float. Example: -89.123456 + cardinal_direction: true # Valid cardinal direction. Examples: "N", "S", "NE", "SE", "none", "" + usa_market_name: true # Check if the value is a valid USA market name. Example: "New York, NY" diff --git a/src/Commands/CreateCsv.php b/src/Commands/CreateCsv.php new file mode 100644 index 00000000..0128051f --- /dev/null +++ b/src/Commands/CreateCsv.php @@ -0,0 +1,59 @@ +setName('create:csv') + ->setDescription('Generate random CSV file by rules from yml file. Data based on fakerphp/faker library.') + ->addArgument( + 'rule-file', + InputArgument::REQUIRED, + 'Path to rule file (yml)', + ) + ->addOption( + 'seed', + null, + InputOption::VALUE_OPTIONAL, + 'Seed for random data generation (fakerphp/faker library)', + ) + ->addOption( + 'to-file', + null, + InputOption::VALUE_OPTIONAL, + 'If set, the generated CSV will be saved to the specified file. ' + . 'Otherwise, the result will be output to the console as STDOUT.', + ); + + parent::configure(); + } + + protected function executeAction(): int + { + throw new \RuntimeException('Not implemented yet'); + } +} diff --git a/src/Commands/CreateSchema.php b/src/Commands/CreateSchema.php new file mode 100644 index 00000000..feadeafa --- /dev/null +++ b/src/Commands/CreateSchema.php @@ -0,0 +1,59 @@ +setName('create:schema') + ->setDescription('Generate random CSV file by rules from yml file. Data based on fakerphp/faker library.') + ->addArgument( + 'rule-file', + InputArgument::REQUIRED, + 'Path to rule file (yml)', + ) + ->addOption( + 'seed', + null, + InputOption::VALUE_OPTIONAL, + 'Seed for random data generation (fakerphp/faker library)', + ) + ->addOption( + 'to-file', + null, + InputOption::VALUE_OPTIONAL, + 'If set, the generated CSV will be saved to the specified file. ' + . 'Otherwise, the result will be output to the console as STDOUT.', + ); + + parent::configure(); + } + + protected function executeAction(): int + { + throw new \RuntimeException('Not implemented yet'); + } +} diff --git a/src/Commands/ValidateCsv.php b/src/Commands/ValidateCsv.php new file mode 100644 index 00000000..091396c3 --- /dev/null +++ b/src/Commands/ValidateCsv.php @@ -0,0 +1,132 @@ +setName('validate:csv') + ->setDescription('Validate CSV file by rule') + ->addOption( + 'csv', + 'c', + InputOption::VALUE_REQUIRED, + 'CSV filepath to validate. If not set or empty, then the STDIN is used.', + ) + ->addOption( + 'schema', + 's', + InputOption::VALUE_REQUIRED, + 'Schema rule filepath', + ) + ->addOption( + 'output', + 'o', + InputOption::VALUE_REQUIRED, + 'Report output format. Available options: ' . + \implode(', ', ErrorSuite::getAvaiableRenderFormats()) . '', + ErrorSuite::RENDER_TABLE, + ); + + parent::configure(); + } + + protected function executeAction(): int + { + $csvFilename = $this->getCsvFilepath(); + $schemaFilename = $this->getSchemaFilepath(); + + $csvFile = new CsvFile($csvFilename, $schemaFilename); + $errorSuite = $csvFile->validate(); + if ($errorSuite->count() > 0) { + $this->_( + $errorSuite->render($this->getOptString('output')), + $this->isTextMode() ? OutLvl::E : OutLvl::DEFAULT, + ); + + if ($this->isTextMode()) { + $this->_( + 'CSV file is not valid! Found ' . $errorSuite->count() . ' errors.', + OutLvl::E, + ); + } + + return self::FAILURE; + } + + if ($this->isTextMode()) { + $this->_('Looks good!'); + } + + return self::SUCCESS; + } + + private function getCsvFilepath(): string + { + $csvFilename = $this->getOptString('csv'); + + if (\file_exists($csvFilename) === false) { + throw new Exception("CSV file not found: {$csvFilename}"); + } + + if ($this->isTextMode()) { + $this->_('CSV : ' . \realpath($csvFilename)); + } + + return $csvFilename; + } + + private function getSchemaFilepath(): string + { + $schemaFilename = $this->getOptString('schema'); + + if (\file_exists($schemaFilename) === false) { + throw new Exception("Schema file not found: {$schemaFilename}"); + } + + if ($this->isTextMode()) { + $this->_('Schema : ' . \realpath($schemaFilename)); + } + + return $schemaFilename; + } + + private function isTextMode(): bool + { + return $this->getOutputMode() === ErrorSuite::RENDER_TEXT + || $this->getOutputMode() === ErrorSuite::RENDER_GITHUB + || $this->getOutputMode() === ErrorSuite::RENDER_TEAMCITY + || $this->getOutputMode() === ErrorSuite::RENDER_TABLE; + } + + private function getOutputMode(): string + { + return $this->getOptString('output', ErrorSuite::RENDER_TABLE, ErrorSuite::getAvaiableRenderFormats()); + } +} diff --git a/src/Commands/ValidateDir.php b/src/Commands/ValidateDir.php new file mode 100644 index 00000000..c3785aba --- /dev/null +++ b/src/Commands/ValidateDir.php @@ -0,0 +1,50 @@ +setName('validate:dir') + ->setDescription('Validate CSV file(s) by rules from yml file(s)') + ->addArgument( + 'csv-file-or-dir', + InputArgument::REQUIRED, + 'Path to CSV file or directory with CSV files', + ) + ->addArgument( + 'rule-file-or-dir', + InputArgument::REQUIRED, + 'Path to rule file (yml) or directory with rule files', + ); + + parent::configure(); + } + + protected function executeAction(): int + { + throw new \RuntimeException('Not implemented yet'); + } +} diff --git a/src/Csv/Column.php b/src/Csv/Column.php new file mode 100644 index 00000000..1cc88b66 --- /dev/null +++ b/src/Csv/Column.php @@ -0,0 +1,133 @@ + '', + 'name' => '', + 'description' => '', + 'type' => 'base', // TODO: class + 'required' => false, + 'allow_empty' => false, + 'regex' => null, + 'rules' => [], + 'aggregate_rules' => [], + ]; + + private int $id; + private Data $column; + private array $rules; + private array $aggregateRules; + + public function __construct(int $id, array $config) + { + $this->id = $id; + $this->column = new Data($config); + $this->rules = $this->prepareRuleSet('rules'); + $this->aggregateRules = $this->prepareRuleSet('aggregate_rules'); + } + + public function getName(): string + { + return $this->column->getString('name', self::FALLBACK_VALUES['name']); + } + + public function getId(): int + { + return $this->id; + } + + public function getDescription(): string + { + return $this->column->getString('description', self::FALLBACK_VALUES['description']); + } + + public function getHumanName(): string + { + return $this->getId() . ':' . \trim($this->getName()); + } + + public function getKey(): string + { + if ($this->getName() !== '') { + return $this->getName(); + } + + return (string)$this->getId(); + } + + public function getType(): string + { + return $this->column->getString('type', self::FALLBACK_VALUES['type']); + } + + public function isRequired(): bool + { + return $this->column->getBool('required', self::FALLBACK_VALUES['required']); + } + + public function getRegex(): ?string + { + $regex = $this->column->getStringNull('regex', self::FALLBACK_VALUES['regex']); + + return Utils::prepareRegex($regex); + } + + public function getRules(): array + { + return $this->rules; + } + + public function getAggregateRules(): array + { + return $this->aggregateRules; + } + + public function getInherit(): string + { + return $this->column->getString('inherit', self::FALLBACK_VALUES['inherit']); + } + + public function validate(string $cellValue, int $line): ErrorSuite + { + return (new Validator($this))->validate($cellValue, $line); + } + + private function prepareRuleSet(string $schemaKey): array + { + $rules = []; + + $ruleSetConfig = $this->column->getSelf($schemaKey, [])->getArrayCopy(); + + foreach ($ruleSetConfig as $ruleName => $ruleValue) { + if (\str_starts_with((string)$ruleName, 'custom_')) { + $rules[$ruleName] = \array_merge(['class' => '', 'args' => []], $ruleValue); + } else { + $rules[$ruleName] = $ruleValue; + } + } + + return $rules; + } +} diff --git a/src/Csv/CsvFile.php b/src/Csv/CsvFile.php new file mode 100644 index 00000000..d39e35ac --- /dev/null +++ b/src/Csv/CsvFile.php @@ -0,0 +1,160 @@ +csvFilename = $csvFilename; + $this->schema = new Schema($csvSchemaFilenameOrArray); + $this->structure = $this->schema->getCsvStructure(); + $this->reader = $this->prepareReader(); + } + + public function getCsvFilename(): string + { + return \pathinfo((string)\realpath($this->csvFilename), \PATHINFO_BASENAME); + } + + public function getCsvStructure(): ParseConfig + { + return $this->structure; + } + + /** + * @return string[] + */ + public function getHeader(): array + { + if ($this->structure->isHeader()) { + return $this->reader->getHeader(); + } + + return []; + } + + public function getRecords(): \Iterator + { + return $this->reader->getRecords($this->getHeader()); + } + + public function getRecordsChunk(int $offset = 0, int $limit = -1): \League\Csv\TabularDataReader + { + return Statement::create(null, $offset, $limit)->process($this->reader, $this->getHeader()); + } + + public function validate(bool $quickStop = false): ErrorSuite + { + $errors = new ErrorSuite($this->getCsvFilename()); + + $errors->addErrorSuit($this->validateHeader()) + ->addErrorSuit($this->validateEachCell($quickStop)) + ->addErrorSuit(self::validateAggregateRules($quickStop)); + + return $errors; + } + + private function prepareReader(): LeagueReader + { + $reader = LeagueReader::createFromPath($this->csvFilename) + ->setDelimiter($this->structure->getDelimiter()) + ->setEnclosure($this->structure->getEnclosure()) + ->setEscape($this->structure->getQuoteChar()) + ->setHeaderOffset($this->structure->isHeader() ? 0 : null); + + if ($this->structure->isBom()) { + $reader->includeInputBOM(); + } else { + $reader->skipInputBOM(); + } + + return $reader; + } + + private function validateHeader(): ErrorSuite + { + $errors = new ErrorSuite(); + + if (!$this->getCsvStructure()->isHeader()) { + return $errors; + } + + foreach ($this->schema->getColumns() as $column) { + if ($column->getName() === '') { + $error = new Error( + 'csv.header', + "Property \"name\" is not defined in schema: \"{$this->schema->getFilename()}\"", + $column->getHumanName(), + 1, + ); + + $errors->addError($error); + } + } + + return $errors; + } + + private function validateEachCell(bool $quickStop = false): ErrorSuite + { + $errors = new ErrorSuite(); + + foreach ($this->getRecords() as $line => $record) { + $columns = $this->schema->getColumnsMappedByHeader($this->getHeader()); + + foreach ($columns as $column) { + if ($column === null) { + continue; + } + + $errors->addErrorSuit($column->validate($record[$column->getKey()], (int)$line + 1)); + if ($quickStop && $errors->count() > 0) { + return $errors; + } + } + } + + return $errors; + } + + private static function validateAggregateRules(bool $quickStop = false): ErrorSuite + { + $errors = new ErrorSuite(); + + if ($quickStop && $errors->count() > 0) { + return $errors; + } + + return new ErrorSuite(); + } +} diff --git a/src/Csv/Exception.php b/src/Csv/Exception.php new file mode 100644 index 00000000..2e1cca41 --- /dev/null +++ b/src/Csv/Exception.php @@ -0,0 +1,21 @@ + null, + 'bom' => false, + 'delimiter' => ',', + 'quote_char' => '\\', + 'enclosure' => '"', + 'encoding' => 'utf-8', + 'header' => true, + 'strict_column_order' => false, + 'other_columns_possible' => false, + ]; + + private Data $structure; + + public function __construct(array $config) + { + $this->structure = new Data($config); + } + + public function getInherit(): ?string + { + return $this->structure->getStringNull('inherit', self::FALLBACK_VALUES['inherit']); + } + + public function isBom(): bool + { + return $this->structure->getBool('bom', self::FALLBACK_VALUES['bom']); + } + + public function getDelimiter(): string + { + $value = $this->structure->getString('delimiter', self::FALLBACK_VALUES['delimiter']); + if (\strlen($value) === 1) { + return $value; + } + + throw new \InvalidArgumentException('Delimiter must be a single character'); + } + + public function getQuoteChar(): string + { + $value = $this->structure->getString('quote_char', self::FALLBACK_VALUES['quote_char']); + if (\strlen($value) === 1) { + return $value; + } + + throw new \InvalidArgumentException('Quote char must be a single character'); + } + + public function getEnclosure(): string + { + $value = $this->structure->getString('enclosure', self::FALLBACK_VALUES['enclosure']); + + if (\strlen($value) === 1) { + return $value; + } + + throw new \InvalidArgumentException('Enclosure must be a single character'); + } + + public function getEncoding(): string + { + $encoding = \strtolower(\trim($this->structure->getString('encoding', self::FALLBACK_VALUES['encoding']))); + + $availableOptions = [ // TODO: add flexible handler for this + self::ENCODING_UTF8, + self::ENCODING_UTF16, + self::ENCODING_UTF32, + ]; + + $result = \in_array($encoding, $availableOptions, true) ? $encoding : null; + if ($result !== null) { + return $result; + } + + throw new \InvalidArgumentException("Invalid encoding: {$encoding}"); + } + + public function isHeader(): bool + { + return $this->structure->getBool('header', self::FALLBACK_VALUES['header']); + } + + public function isStrictColumnOrder(): bool + { + return $this->structure->getBool('strict_column_order', self::FALLBACK_VALUES['strict_column_order']); + } + + public function isOtherColumnsPossible(): bool + { + return $this->structure->getBool('other_columns_possible', self::FALLBACK_VALUES['other_columns_possible']); + } + + public function getArrayCopy(): array + { + return [ + // System rules + // 'inherit' => $this->getInherit(), // TODO Implement me + // Reading rules + 'header' => $this->isHeader(), + 'delimiter' => $this->getDelimiter(), + 'quote_char' => $this->getQuoteChar(), + 'enclosure' => $this->getEnclosure(), + 'encoding' => $this->getEncoding(), + 'bom' => $this->isBom(), + // Global validation rules + // 'strict_column_order' => $this->isStrictColumnOrder(), // TODO Implement me + // 'other_columns_possible' => $this->isOtherColumnsPossible(), // TODO Implement me + ]; + } +} diff --git a/src/Exception.php b/src/Exception.php new file mode 100644 index 00000000..1780922a --- /dev/null +++ b/src/Exception.php @@ -0,0 +1,21 @@ +filename = '_custom_array_'; + $this->data = new Data($csvSchemaFilenameOrArray); + } elseif ( + \is_string($csvSchemaFilenameOrArray) + && $csvSchemaFilenameOrArray !== '' + && \file_exists($csvSchemaFilenameOrArray) + ) { + $this->filename = $csvSchemaFilenameOrArray; + $this->data = new Data(); + $fileExtension = \pathinfo($csvSchemaFilenameOrArray, \PATHINFO_EXTENSION); + + if ($fileExtension === 'yml' || $fileExtension === 'yaml') { + $this->data = yml($csvSchemaFilenameOrArray); + } elseif ($fileExtension === 'json') { + $this->data = json($csvSchemaFilenameOrArray); + } elseif ($fileExtension === 'php') { + $this->data = phpArray($csvSchemaFilenameOrArray); + } else { + throw new \InvalidArgumentException("Unsupported file extension: {$fileExtension}"); + } + } else { + $this->filename = null; + $this->data = new Data(); + } + + $this->columns = $this->prepareColumns(); + } + + public function getFilename(): ?string + { + return $this->filename; + } + + public function getCsvStructure(): ParseConfig + { + return new ParseConfig($this->data->getArray('csv')); + } + + /** + * @return Column[] + */ + public function getColumns(): array + { + return $this->columns; + } + + /** + * @return Column[]|null[] + * @phan-suppress PhanPartialTypeMismatchReturn + */ + public function getColumnsMappedByHeader(array $header): array + { + $map = []; + + foreach ($header as $headerName) { + $map[$headerName] = $this->columns[$headerName] ?? null; + } + + return $map; + } + + public function getColumn(int|string $columNameOrId): ?Column + { + if (\is_int($columNameOrId)) { + $column = \array_values($this->getColumns())[$columNameOrId] ?? null; + } else { + $column = $this->getColumns()[$columNameOrId] ?? null; + } + + if ($column === null) { + throw new Exception("Column \"{$columNameOrId}\" not found in schema \"{$this->filename}\""); + } + + return $column; + } + + public function getFinenamePattern(): ?string + { + return $this->data->getStringNull('finename_pattern'); + } + + public function getIncludes(): array + { + $result = []; + + foreach ($this->data->getArray('includes') as $includedPath) { + [$schemaPath, $alias] = \explode(' as ', $includedPath); + + $schemaPath = \trim($schemaPath); + $alias = \trim($alias); + + $result[$alias] = $schemaPath; + } + + return $result; + } + + /** + * @return Column[] + */ + private function prepareColumns(): array + { + $result = []; + + foreach ($this->data->getArray('columns') as $columnId => $columnPreferences) { + $column = new Column((int)$columnId, $columnPreferences); + + $result[$column->getKey()] = $column; + } + + return $result; + } +} diff --git a/src/Utils.php b/src/Utils.php new file mode 100644 index 00000000..dd26fed0 --- /dev/null +++ b/src/Utils.php @@ -0,0 +1,47 @@ +getRuleCode()}\" at line {$this->getLine()}, " . + "column \"{$this->getColumnName()}\". {$this->getMessage()}."; + } + + public function getRuleCode(): string + { + return $this->ruleCode; + } + + public function getMessage(): string + { + return \rtrim($this->message, '.'); + } + + public function getColumnName(): string + { + return $this->columnName; + } + + public function getLine(): int + { + return $this->line; + } + + public function toArray(): array + { + return [ + 'ruleCode' => $this->ruleCode, + 'message' => $this->message, + 'columnName' => $this->columnName, + 'line' => $this->line, + ]; + } +} diff --git a/src/Validators/ErrorSuite.php b/src/Validators/ErrorSuite.php new file mode 100644 index 00000000..35055d6b --- /dev/null +++ b/src/Validators/ErrorSuite.php @@ -0,0 +1,169 @@ +render(self::RENDER_TEXT); + } + + public function render(string $mode = self::RENDER_TEXT): string + { + if ($this->count() === 0) { + return ''; + } + + $sourceSuite = $this->prepareSourceSuite(); + $map = [ + self::RENDER_TEXT => fn (): string => $this->renderPlainText(), + self::RENDER_TABLE => fn (): string => $this->renderTable(), + self::RENDER_GITHUB => static fn (): string => (new GithubCliConverter())->fromInternal($sourceSuite), + self::RENDER_GITLAB => static fn (): string => (new GitLabJsonConverter())->fromInternal($sourceSuite), + self::RENDER_TEAMCITY => static fn (): string => (new TeamCityTestsConverter())->fromInternal($sourceSuite), + self::RENDER_JUNIT => static fn (): string => (new JUnitConverter())->fromInternal($sourceSuite), + ]; + + if (isset($map[$mode])) { + return $map[$mode](); + } + + throw new Exception("Unknown error render mode: {$mode}"); + } + + /** + * @return Error[] + */ + public function getErrors(): array + { + return $this->errors; + } + + public function addError(?Error $error): self + { + if ($error === null) { + return $this; + } + + $this->errors[] = $error; + + return $this; + } + + public function addErrorSuit(?self $errorSuite): self + { + if ($errorSuite === null) { + return $this; + } + + $this->errors = \array_merge($this->getErrors(), $errorSuite->getErrors()); + + return $this; + } + + public function count(): int + { + return \count($this->errors); + } + + public function get(int $index): ?Error + { + return $this->errors[$index] ?? null; + } + + public static function getAvaiableRenderFormats(): array + { + return [ + self::RENDER_TEXT, + self::RENDER_TABLE, + self::RENDER_GITHUB, + self::RENDER_GITLAB, + self::RENDER_TEAMCITY, + self::RENDER_JUNIT, + ]; + } + + private function renderPlainText(): string + { + $result = []; + + foreach ($this->errors as $error) { + $result[] = (string)$error; + } + + return \implode("\n", $result); + } + + private function renderTable(): string + { + $buffer = new BufferedOutput(); + $table = (new Table($buffer)) + ->setHeaderTitle($this->csvFilename) + ->setFooterTitle($this->csvFilename) + ->setHeaders(['Line', 'id:Column', 'Rule', 'Message']) + ->setColumnMaxWidth(0, 10) + ->setColumnMaxWidth(1, 20) + ->setColumnMaxWidth(2, 20) + ->setColumnMaxWidth(3, 60); + + foreach ($this->errors as $error) { + $table->addRow([$error->getLine(), $error->getColumnName(), $error->getRuleCode(), $error->getMessage()]); + } + + $table->render(); + + return $buffer->fetch(); + } + + private function prepareSourceSuite(): SourceSuite + { + $suite = new SourceSuite($this->csvFilename); + + foreach ($this->errors as $error) { + $caseName = $error->getRuleCode() . ' at column ' . $error->getColumnName(); + $case = $suite->addTestCase($caseName); + $case->line = $error->getLine(); + $case->file = $this->csvFilename; + $case->errOut = $error->getMessage(); + } + + return $suite; + } +} diff --git a/src/Validators/Exception.php b/src/Validators/Exception.php new file mode 100644 index 00000000..46a595ca --- /dev/null +++ b/src/Validators/Exception.php @@ -0,0 +1,21 @@ +columnNameId = $columnNameId; + $this->options = $options; + $this->ruleCode = $this->getRuleCode(); + } + + public function validate(?string $cellValue, int $line = 0): ?Error + { + $error = $this->validateRule($cellValue); + if ($error !== null) { + return new Error($this->ruleCode, $error, $this->columnNameId, $line); + } + + return null; + } + + protected function getOptionAsBool(): bool + { + return bool($this->options); + } + + protected function getOptionAsString(): string + { + if (\is_array($this->options)) { + return (string)json($this->options); + } + + return (string)$this->options; + } + + protected function getOptionAsInt(): int + { + return int($this->options); + } + + protected function getOptionAsFloat(): float + { + return float($this->options); + } + + protected function getOptionAsArray(): array + { + return (array)$this->options; + } + + protected function getOptionAsData(): Data + { + return data($this->options); + } + + protected function getOptionAsDate(): \DateTimeImmutable + { + return new \DateTimeImmutable($this->getOptionAsString(), new \DateTimeZone('UTC')); + } + + private function getRuleCode(): string + { + return Utils::camelToKebabCase((new \ReflectionClass($this))->getShortName()); + } +} diff --git a/src/Validators/Rules/AllowValues.php b/src/Validators/Rules/AllowValues.php new file mode 100644 index 00000000..ed83ecd4 --- /dev/null +++ b/src/Validators/Rules/AllowValues.php @@ -0,0 +1,36 @@ +getOptionAsArray(); + + if (\count($allowedValues) === 0) { + return 'Allowed values are not defined'; + } + + if (!\in_array($cellValue, $allowedValues, true)) { + return "Value \"{$cellValue}\" is not allowed. " . + 'Allowed values: ["' . \implode('", "', $allowedValues) . '"]'; + } + + return null; + } +} diff --git a/src/Validators/Rules/CardinalDirection.php b/src/Validators/Rules/CardinalDirection.php new file mode 100644 index 00000000..f1cf9be9 --- /dev/null +++ b/src/Validators/Rules/CardinalDirection.php @@ -0,0 +1,34 @@ +getOptionAsBool()) { + return null; + } + + return parent::validateRule((string)$cellValue); + } + + public function getOptionAsArray(): array + { + return ['N', 'S', 'E', 'W', 'NE', 'SE', 'NW', 'SW', 'none', '']; + } +} diff --git a/src/Validators/Rules/DateFormat.php b/src/Validators/Rules/DateFormat.php new file mode 100644 index 00000000..3e3e45ea --- /dev/null +++ b/src/Validators/Rules/DateFormat.php @@ -0,0 +1,39 @@ +getOptionAsString(); + if ($expectedDateFormat === '') { + return 'Date format is not defined'; + } + + if ($cellValue === null || $cellValue === '') { + return 'Date format of value "" is not valid. Expected format: "' . $expectedDateFormat . '"'; + } + + $date = \DateTimeImmutable::createFromFormat($expectedDateFormat, $cellValue); + if ($date === false || $date->format($expectedDateFormat) !== $cellValue) { + return "Date format of value \"{$cellValue}\" is not valid. Expected format: \"{$expectedDateFormat}\""; + } + + return null; + } +} diff --git a/src/Validators/Rules/ExactValue.php b/src/Validators/Rules/ExactValue.php new file mode 100644 index 00000000..31f71d80 --- /dev/null +++ b/src/Validators/Rules/ExactValue.php @@ -0,0 +1,29 @@ +getOptionAsString() !== (string)$cellValue) { + return "Value \"{$cellValue}\" is not strict equal to \"{$this->getOptionAsString()}\""; + } + + return null; + } +} diff --git a/src/Validators/Rules/IsBool.php b/src/Validators/Rules/IsBool.php new file mode 100644 index 00000000..e4260f5b --- /dev/null +++ b/src/Validators/Rules/IsBool.php @@ -0,0 +1,34 @@ +getOptionAsBool()) { + return null; + } + + return parent::validateRule(\strtolower((string)$cellValue)); + } + + public function getOptionAsArray(): array + { + return ['true', 'false']; + } +} diff --git a/src/Validators/Rules/IsDomain.php b/src/Validators/Rules/IsDomain.php new file mode 100644 index 00000000..88bea459 --- /dev/null +++ b/src/Validators/Rules/IsDomain.php @@ -0,0 +1,35 @@ +getOptionAsBool()) { + return null; + } + + $domainPattern = '/^(?!-)[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{2,})$/'; + + if (\preg_match($domainPattern, (string)$cellValue) === 0) { + return "Value \"{$cellValue}\" is not a valid domain"; + } + + return null; + } +} diff --git a/src/Validators/Rules/IsEmail.php b/src/Validators/Rules/IsEmail.php new file mode 100644 index 00000000..010f51ea --- /dev/null +++ b/src/Validators/Rules/IsEmail.php @@ -0,0 +1,33 @@ +getOptionAsBool()) { + return null; + } + + if (\filter_var($cellValue, \FILTER_VALIDATE_EMAIL) === false) { + return "Value \"{$cellValue}\" is not a valid email"; + } + + return null; + } +} diff --git a/src/Validators/Rules/IsFloat.php b/src/Validators/Rules/IsFloat.php new file mode 100644 index 00000000..74b61dea --- /dev/null +++ b/src/Validators/Rules/IsFloat.php @@ -0,0 +1,33 @@ +getOptionAsBool()) { + return null; + } + + if (\preg_match('/^-?\d+(\.\d+)?$/', (string)$cellValue) === 0) { + return "Value \"{$cellValue}\" is not a float number"; + } + + return null; + } +} diff --git a/src/Validators/Rules/IsInt.php b/src/Validators/Rules/IsInt.php new file mode 100644 index 00000000..069fca8f --- /dev/null +++ b/src/Validators/Rules/IsInt.php @@ -0,0 +1,33 @@ +getOptionAsBool()) { + return null; + } + + if (\preg_match('/^-?\d+$/', (string)$cellValue) === 0) { + return "Value \"{$cellValue}\" is not an integer"; + } + + return null; + } +} diff --git a/src/Validators/Rules/IsIp.php b/src/Validators/Rules/IsIp.php new file mode 100644 index 00000000..814c3bf1 --- /dev/null +++ b/src/Validators/Rules/IsIp.php @@ -0,0 +1,33 @@ +getOptionAsBool()) { + return null; + } + + if (\filter_var($cellValue, \FILTER_VALIDATE_IP) === false) { + return "Value \"{$cellValue}\" is not a valid IP"; + } + + return null; + } +} diff --git a/src/Validators/Rules/IsLatitude.php b/src/Validators/Rules/IsLatitude.php new file mode 100644 index 00000000..5085519e --- /dev/null +++ b/src/Validators/Rules/IsLatitude.php @@ -0,0 +1,42 @@ +getOptionAsBool()) { + return null; + } + + $result = parent::validateRule($cellValue); + if ($result !== null) { + return $result; + } + + $latitude = (float)$cellValue; + if ($latitude < $this->min || $latitude > $this->max) { + return "Value \"{$cellValue}\" is not a valid latitude ({$this->min} <= x <= {$this->max})"; + } + + return null; + } +} diff --git a/src/Validators/Rules/IsLongitude.php b/src/Validators/Rules/IsLongitude.php new file mode 100644 index 00000000..97b06c28 --- /dev/null +++ b/src/Validators/Rules/IsLongitude.php @@ -0,0 +1,42 @@ +getOptionAsBool()) { + return null; + } + + $result = parent::validateRule($cellValue); + if ($result !== null) { + return $result; + } + + $longitude = (float)$cellValue; + if ($longitude < $this->min || $longitude > $this->max) { + return "Value \"{$cellValue}\" is not a valid longitude ({$this->min} <= x <= {$this->max})"; + } + + return null; + } +} diff --git a/src/Validators/Rules/IsUrl.php b/src/Validators/Rules/IsUrl.php new file mode 100644 index 00000000..8bc1a242 --- /dev/null +++ b/src/Validators/Rules/IsUrl.php @@ -0,0 +1,33 @@ +getOptionAsBool()) { + return null; + } + + if (\filter_var($cellValue, \FILTER_VALIDATE_URL) === false) { + return "Value \"{$cellValue}\" is not a valid URL"; + } + + return null; + } +} diff --git a/src/Validators/Rules/IsUuid4.php b/src/Validators/Rules/IsUuid4.php new file mode 100644 index 00000000..86a5b55b --- /dev/null +++ b/src/Validators/Rules/IsUuid4.php @@ -0,0 +1,35 @@ +getOptionAsBool()) { + return null; + } + + $uuid4 = '/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89ABab][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/'; + + if (\preg_match($uuid4, (string)$cellValue) === 0) { + return 'Value is not a valid UUID v4'; + } + + return null; + } +} diff --git a/src/Validators/Rules/Max.php b/src/Validators/Rules/Max.php new file mode 100644 index 00000000..9ce9b0a8 --- /dev/null +++ b/src/Validators/Rules/Max.php @@ -0,0 +1,34 @@ +getOptionAsFloat() < (float)$cellValue) { + return "Value \"{$cellValue}\" is greater than \"{$this->getOptionAsFloat()}\""; + } + + return null; + } +} diff --git a/src/Validators/Rules/MaxDate.php b/src/Validators/Rules/MaxDate.php new file mode 100644 index 00000000..434ceeb2 --- /dev/null +++ b/src/Validators/Rules/MaxDate.php @@ -0,0 +1,33 @@ +getOptionAsDate(); + $cellDate = new \DateTimeImmutable((string)$cellValue); + + if ($cellDate->getTimestamp() > $minDate->getTimestamp()) { + return "Value \"{$cellValue}\" is more than the maximum " . + "date \"{$minDate->format(\DATE_RFC3339_EXTENDED)}\""; + } + + return null; + } +} diff --git a/src/Validators/Rules/MaxLength.php b/src/Validators/Rules/MaxLength.php new file mode 100644 index 00000000..6cac2d8f --- /dev/null +++ b/src/Validators/Rules/MaxLength.php @@ -0,0 +1,32 @@ +getOptionAsInt(); + $length = \mb_strlen((string)$cellValue); + + if ($length > $minLength) { + return "Value \"{$cellValue}\" (legth: {$length}) is too long. Max length is {$minLength}"; + } + + return null; + } +} diff --git a/src/Validators/Rules/Min.php b/src/Validators/Rules/Min.php new file mode 100644 index 00000000..06ec2e21 --- /dev/null +++ b/src/Validators/Rules/Min.php @@ -0,0 +1,34 @@ +getOptionAsFloat() > (float)$cellValue) { + return "Value \"{$cellValue}\" is less than \"{$this->getOptionAsFloat()}\""; + } + + return null; + } +} diff --git a/src/Validators/Rules/MinDate.php b/src/Validators/Rules/MinDate.php new file mode 100644 index 00000000..225a4c43 --- /dev/null +++ b/src/Validators/Rules/MinDate.php @@ -0,0 +1,33 @@ +getOptionAsDate(); + $cellDate = new \DateTimeImmutable((string)$cellValue); + + if ($cellDate->getTimestamp() < $minDate->getTimestamp()) { + return "Value \"{$cellValue}\" is less than the minimum " . + "date \"{$minDate->format(\DATE_RFC3339_EXTENDED)}\""; + } + + return null; + } +} diff --git a/src/Validators/Rules/MinLength.php b/src/Validators/Rules/MinLength.php new file mode 100644 index 00000000..dab97808 --- /dev/null +++ b/src/Validators/Rules/MinLength.php @@ -0,0 +1,32 @@ +getOptionAsInt(); + $length = \mb_strlen((string)$cellValue); + + if ($length < $minLength) { + return "Value \"{$cellValue}\" (legth: {$length}) is too short. Min length is {$minLength}"; + } + + return null; + } +} diff --git a/src/Validators/Rules/NotEmpty.php b/src/Validators/Rules/NotEmpty.php new file mode 100644 index 00000000..b99339d7 --- /dev/null +++ b/src/Validators/Rules/NotEmpty.php @@ -0,0 +1,33 @@ +getOptionAsBool()) { + return null; + } + + if ($cellValue === null || $cellValue === '') { + return 'Value is empty'; + } + + return null; + } +} diff --git a/src/Validators/Rules/OnlyCapitalize.php b/src/Validators/Rules/OnlyCapitalize.php new file mode 100644 index 00000000..49771bfd --- /dev/null +++ b/src/Validators/Rules/OnlyCapitalize.php @@ -0,0 +1,33 @@ +getOptionAsBool()) { + return null; + } + + if ($cellValue !== null && $cellValue !== \ucfirst($cellValue)) { + return "Value \"{$cellValue}\" should be in capitalize"; + } + + return null; + } +} diff --git a/src/Validators/Rules/OnlyLowercase.php b/src/Validators/Rules/OnlyLowercase.php new file mode 100644 index 00000000..3e4c8e4c --- /dev/null +++ b/src/Validators/Rules/OnlyLowercase.php @@ -0,0 +1,33 @@ +getOptionAsBool()) { + return null; + } + + if ($cellValue !== null && $cellValue !== \mb_strtolower($cellValue)) { + return "Value \"{$cellValue}\" should be in lowercase"; + } + + return null; + } +} diff --git a/src/Validators/Rules/OnlyTrimed.php b/src/Validators/Rules/OnlyTrimed.php new file mode 100644 index 00000000..1da94d95 --- /dev/null +++ b/src/Validators/Rules/OnlyTrimed.php @@ -0,0 +1,33 @@ +getOptionAsBool()) { + return null; + } + + if (\trim((string)$cellValue) !== (string)$cellValue) { + return "Value \"{$cellValue}\" is not trimmed"; + } + + return null; + } +} diff --git a/src/Validators/Rules/OnlyUppercase.php b/src/Validators/Rules/OnlyUppercase.php new file mode 100644 index 00000000..f3014b36 --- /dev/null +++ b/src/Validators/Rules/OnlyUppercase.php @@ -0,0 +1,33 @@ +getOptionAsBool()) { + return null; + } + + if ($cellValue !== null && \mb_strtoupper($cellValue, 'UTF-8') !== $cellValue) { + return "Value \"{$cellValue}\" is not uppercase"; + } + + return null; + } +} diff --git a/src/Validators/Rules/Precision.php b/src/Validators/Rules/Precision.php new file mode 100644 index 00000000..e1bfe56c --- /dev/null +++ b/src/Validators/Rules/Precision.php @@ -0,0 +1,44 @@ +getOptionAsInt() !== $valuePrecision) { + return "Value \"{$cellValue}\" has a precision of {$valuePrecision} " . + "but should have a precision of {$this->getOptionAsInt()}"; + } + + return null; + } + + private static function getFloatPrecision(?string $cellValue): int + { + $floatAsString = (string)$cellValue; + $dotPosition = \strpos($floatAsString, '.'); + + if ($dotPosition === false) { + return 0; + } + + return \strlen($floatAsString) - $dotPosition - 1; + } +} diff --git a/src/Validators/Rules/Regex.php b/src/Validators/Rules/Regex.php new file mode 100644 index 00000000..27b707ea --- /dev/null +++ b/src/Validators/Rules/Regex.php @@ -0,0 +1,37 @@ +getOptionAsString()); + + if ($regex === null || $regex === '') { + return 'Regex pattern is not defined'; + } + + if (\preg_match($regex, (string)$cellValue) === 0) { + return "Value \"{$cellValue}\" does not match the pattern \"{$regex}\""; + } + + return null; + } +} diff --git a/src/Validators/Rules/RuleException.php b/src/Validators/Rules/RuleException.php new file mode 100644 index 00000000..48ed9cb6 --- /dev/null +++ b/src/Validators/Rules/RuleException.php @@ -0,0 +1,21 @@ +getOptionAsBool()) { + return null; + } + + if (\preg_match('/^[A-Za-z0-9\s-]+, [A-Z]{2}$/u', (string)$cellValue) === 0) { + return "Invalid market name format for value \"{$cellValue}\". " . + 'Market name must have format "New York, NY"'; + } + + return null; + } +} diff --git a/src/Validators/Ruleset.php b/src/Validators/Ruleset.php new file mode 100644 index 00000000..42efff96 --- /dev/null +++ b/src/Validators/Ruleset.php @@ -0,0 +1,63 @@ +columnNameId = $columnNameId; + $this->rules = []; + + foreach ($rules as $ruleName => $options) { + $this->rules[] = $this->createRule((string)$ruleName, $options); + } + } + + /** + * @psalm-suppress MoreSpecificReturnType + * @psalm-suppress LessSpecificReturnStatement + */ + public function createRule(string $ruleName, null|array|bool|float|int|string $options = null): AbstarctRule + { + $classname = __NAMESPACE__ . '\\Rules\\' . Utils::kebabToCamelCase($ruleName); + if (\class_exists($classname)) { + // @phpstan-ignore-next-line + return new $classname($this->columnNameId, $options); + } + + throw new Exception("Rule \"{$ruleName}\" not found. Expected class: \"{$classname}\""); + } + + public function validate(?string $cellValue, int $line): ErrorSuite + { + $errors = new ErrorSuite(); + + foreach ($this->rules as $rule) { + $errors->addError($rule->validate($cellValue, $line)); + } + + return $errors; + } +} diff --git a/src/Validators/Validator.php b/src/Validators/Validator.php new file mode 100644 index 00000000..2d8c857c --- /dev/null +++ b/src/Validators/Validator.php @@ -0,0 +1,34 @@ +ruleset = new Ruleset($column->getRules(), $column->getHumanName()); + } + + public function validate(?string $cellValue, int $line): ErrorSuite + { + return $this->ruleset->validate($cellValue, $line); + } +} diff --git a/tests/Blueprint/CsvReaderTest.php b/tests/Blueprint/CsvReaderTest.php new file mode 100644 index 00000000..4291b685 --- /dev/null +++ b/tests/Blueprint/CsvReaderTest.php @@ -0,0 +1,82 @@ +getCsvFilename()); + + isSame([], $csv->getHeader()); + + isSame([ + ['1', 'true'], + ['2', 'true'], + ['3', 'false'], + ], $this->fetchRows($csv->getRecords())); + + isSame([['2', 'true']], $this->fetchRows($csv->getRecordsChunk(1, 1))); + + isSame([['2', 'true'], ['3', 'false']], $this->fetchRows($csv->getRecordsChunk(1))); + } + + public function testReadCsvFileWithHeader(): void + { + $csv = new CsvFile(self::CSV_SIMPLE_HEADER, self::SCHEMA_SIMPLE_HEADER); + isSame('simple_header.csv', $csv->getCsvFilename()); + + isSame(['seq', 'bool', 'exact'], $csv->getHeader()); + + isSame([ + ['seq' => '1', 'bool' => 'true', 'exact' => '1'], + ['seq' => '2', 'bool' => 'true', 'exact' => '1'], + ['seq' => '3', 'bool' => 'false', 'exact' => '1'], + ], $this->fetchRows($csv->getRecords())); + + isSame( + [['seq' => '2', 'bool' => 'true', 'exact' => '1']], + $this->fetchRows($csv->getRecordsChunk(1, 1)), + ); + + isSame( + [['seq' => '2', 'bool' => 'true', 'exact' => '1'], ['seq' => '3', 'bool' => 'false', 'exact' => '1']], + $this->fetchRows($csv->getRecordsChunk(1, 2)), + ); + } + + private function fetchRows(iterable $records): array + { + return \array_reduce(\iterator_to_array($records), static function ($acc, $record) { + $acc[] = $record; + + return $acc; + }, []); + } +} diff --git a/tests/Blueprint/MiscTest.php b/tests/Blueprint/MiscTest.php new file mode 100644 index 00000000..09a91b88 --- /dev/null +++ b/tests/Blueprint/MiscTest.php @@ -0,0 +1,165 @@ +findArray('columns.0.rules'); + $rulesInConfig = \array_keys($rulesInConfig); + \sort($rulesInConfig); + + $finder = (new Finder()) + ->files() + ->in(PROJECT_ROOT . '/src/Validators/Rules') + ->ignoreDotFiles(false) + ->ignoreVCS(true) + ->name('/\\.php$/'); + + foreach ($finder as $file) { + $ruleName = Utils::camelToKebabCase($file->getFilenameWithoutExtension()); + $excludeRules = [ + 'abstarct_rule', + 'exception', + 'rule_exception', + ]; + + if (\in_array($ruleName, $excludeRules, true)) { + continue; + } + + $rulesInCode[] = $ruleName; + } + \sort($rulesInCode); + + isSame($rulesInCode, $rulesInConfig); + } + + public function testCsvStrutureDefaultValues(): void + { + $defaultsInDoc = yml(PROJECT_ROOT . '/schema-examples/full.yml')->findArray('csv'); + + $schema = new Schema([]); + $schema->getCsvStructure()->getArrayCopy(); + + isSame($defaultsInDoc, $schema->getCsvStructure()->getArrayCopy()); + } + + public function testCheckYmlSchemaExampleInReadme(): void + { + $this->testCheckExampleInReadme( + PROJECT_ROOT . '/schema-examples/full.yml', + 'yml', + 'YAML format (with comment)', + 12, + ); + } + + public function testCheckPhpSchemaExampleInReadme(): void + { + $this->testCheckExampleInReadme(PROJECT_ROOT . '/schema-examples/full.php', 'php', 'PHP Format', 14); + } + + public function testCheckJsonSchemaExampleInReadme(): void + { + $this->testCheckExampleInReadme(PROJECT_ROOT . '/schema-examples/full.json', 'json', 'JSON Format', 0); + } + + public function testCompareExamplesWithOrig(): void + { + $basepath = PROJECT_ROOT . '/schema-examples/full'; + + $origYml = yml("{$basepath}.yml")->getArrayCopy(); + + // To update examples ONLY!!! + // file_put_contents("{$basepath}.php", (string)phpArray($origYml)); + // file_put_contents("{$basepath}.json", (string)json($origYml)); + + isSame($origYml, phpArray("{$basepath}.php")->getArrayCopy(), 'PHP config is invalid'); + isSame($origYml, json("{$basepath}.json")->getArrayCopy(), 'JSON config is invalid'); + } + + private function testCheckExampleInReadme( + string $filepath, + string $type, + string $title, + int $skipFirstLines = 0, + ): void { + $filepath = \implode( + "\n", + \array_slice(\explode("\n", \file_get_contents($filepath)), $skipFirstLines), + ); + + if ($type === 'php') { + $tmpl = \implode("\n", ['```php', 'getSpoiler("Click to see: {$title}", $tmpl); + + isFileContains($tmpl, PROJECT_ROOT . '/README.md'); + } + + private function getSpoiler(string $title, string $body): string + { + return \implode("\n", [ + '
', + " {$title}", + '', + "{$body}", + '', + '
', + '', + ]); + } +} diff --git a/tests/Blueprint/RulesTest.php b/tests/Blueprint/RulesTest.php new file mode 100644 index 00000000..56f89de0 --- /dev/null +++ b/tests/Blueprint/RulesTest.php @@ -0,0 +1,604 @@ +validate('1')); + isSame(null, $rule->validate('2')); + isSame(null, $rule->validate('3')); + isSame( + '"allow_values" at line 0, column "prop". ' . + 'Value "" is not allowed. Allowed values: ["1", "2", "3"].', + (string)$rule->validate(''), + ); + isSame( + '"allow_values" at line 0, column "prop". ' . + 'Value "invalid" is not allowed. Allowed values: ["1", "2", "3"].', + (string)$rule->validate('invalid'), + ); + + $rule = new AllowValues('prop', ['1', '2', '3', '']); + isSame(null, $rule->validate('')); + + $rule = new AllowValues('prop', ['1', '2', '3', ' ']); + isSame(null, $rule->validate(' ')); + } + + public function testDateFormat(): void + { + $rule = new DateFormat('prop', 'Y-m-d'); + isSame(null, $rule->validate('2000-12-31')); + isSame( + '"date_format" at line 0, column "prop". ' . + 'Date format of value "" is not valid. Expected format: "Y-m-d".', + (string)$rule->validate(''), + ); + isSame( + '"date_format" at line 0, column "prop". ' . + 'Date format of value "2000-01-02 12:34:56" is not valid. Expected format: "Y-m-d".', + (string)$rule->validate('2000-01-02 12:34:56'), + ); + } + + public function testExactValue(): void + { + $rule = new ExactValue('prop', '123'); + isSame(null, $rule->validate('123')); + isSame( + '"exact_value" at line 0, column "prop". Value "" is not strict equal to "123".', + (string)$rule->validate(''), + ); + isSame( + '"exact_value" at line 0, column "prop". Value "2000-01-02" is not strict equal to "123".', + (string)$rule->validate('2000-01-02'), + ); + } + + public function testIsBool(): void + { + $rule = new IsBool('prop', true); + isSame(null, $rule->validate('true')); + isSame(null, $rule->validate('false')); + isSame(null, $rule->validate('TRUE')); + isSame(null, $rule->validate('FALSE')); + isSame(null, $rule->validate('True')); + isSame(null, $rule->validate('False')); + isSame( + '"is_bool" at line 0, column "prop". Value "" is not allowed. Allowed values: ["true", "false"].', + (string)$rule->validate(''), + ); + isSame( + '"is_bool" at line 0, column "prop". Value "1" is not allowed. Allowed values: ["true", "false"].', + (string)$rule->validate('1'), + ); + } + + public function testIsDomain(): void + { + $rule = new IsDomain('prop', true); + isSame(null, $rule->validate('example.com')); + isSame(null, $rule->validate('sub.example.com')); + isSame(null, $rule->validate('sub.sub.example.com')); + isSame(null, $rule->validate('sub.sub-example.com')); + isSame(null, $rule->validate('sub-sub-example.com')); + isSame(null, $rule->validate('sub-sub-example.qwerty')); + isSame( + '"is_domain" at line 0, column "prop". Value "example" is not a valid domain.', + (string)(string)$rule->validate('example'), + ); + isSame( + '"is_domain" at line 0, column "prop". Value "" is not a valid domain.', + (string)$rule->validate(''), + ); + } + + public function testIsEmail(): void + { + $rule = new IsEmail('prop', true); + isSame(null, $rule->validate('user@example.com')); + isSame(null, $rule->validate('user@sub.example.com')); + isSame( + '"is_email" at line 0, column "prop". Value "user:pass@example.com" is not a valid email.', + (string)(string)$rule->validate('user:pass@example.com'), + ); + } + + public function testIsFloat(): void + { + $rule = new IsFloat('prop', true); + isSame(null, $rule->validate('1')); + isSame(null, $rule->validate('01')); + isSame(null, $rule->validate('1.0')); + isSame(null, $rule->validate('01.0')); + isSame(null, $rule->validate('-1')); + isSame(null, $rule->validate('-1.0')); + isSame( + '"is_float" at line 0, column "prop". Value "1.000.000" is not a float number.', + (string)$rule->validate('1.000.000'), + ); + isSame( + '"is_float" at line 0, column "prop". Value "" is not a float number.', + (string)$rule->validate(''), + ); + isSame( + '"is_float" at line 0, column "prop". Value " 1" is not a float number.', + (string)$rule->validate(' 1'), + ); + } + + public function testIsInt(): void + { + $rule = new IsInt('prop', true); + isSame(null, $rule->validate('1')); + isSame(null, $rule->validate('01')); + isSame(null, $rule->validate('0')); + isSame(null, $rule->validate('00')); + isSame(null, $rule->validate('-1')); + isSame( + '"is_int" at line 0, column "prop". Value "1.000.000" is not an integer.', + (string)$rule->validate('1.000.000'), + ); + isSame( + '"is_int" at line 0, column "prop". Value "1.1" is not an integer.', + (string)(string)$rule->validate('1.1'), + ); + isSame( + '"is_int" at line 0, column "prop". Value "1.0" is not an integer.', + (string)$rule->validate('1.0'), + ); + isSame( + '"is_int" at line 0, column "prop". Value "" is not an integer.', + (string)$rule->validate(''), + ); + isSame( + '"is_int" at line 0, column "prop". Value " 1" is not an integer.', + (string)(string)$rule->validate(' 1'), + ); + isSame( + '"is_int" at line 0, column "prop". Value "1 " is not an integer.', + (string)(string)$rule->validate('1 '), + ); + } + + public function testIsIp(): void + { + $rule = new IsIp('prop', true); + isSame(null, $rule->validate('127.0.0.1')); + isSame(null, $rule->validate('0.0.0.0')); + isSame( + '"is_ip" at line 0, column "prop". Value "1.2.3" is not a valid IP.', + (string)$rule->validate('1.2.3'), + ); + } + + public function testIsLatitude(): void + { + $rule = new IsLatitude('prop', true); + isSame(null, $rule->validate('0')); + isSame(null, $rule->validate('90')); + isSame(null, $rule->validate('-90')); + isSame( + '"is_latitude" at line 0, column "prop". Value "123" is not a valid latitude (-90 <= x <= 90).', + (string)$rule->validate('123'), + ); + isSame( + '"is_latitude" at line 0, column "prop". Value "90.1" is not a valid latitude (-90 <= x <= 90).', + (string)$rule->validate('90.1'), + ); + isSame( + '"is_latitude" at line 0, column "prop". Value "90.1.1.1.1" is not a float number.', + (string)$rule->validate('90.1.1.1.1'), + ); + } + + public function testIsLongitude(): void + { + $rule = new IsLongitude('prop', true); + isSame(null, $rule->validate('0')); + isSame(null, $rule->validate('180')); + isSame(null, $rule->validate('-180')); + isSame( + '"is_longitude" at line 0, column "prop". Value "1230" is not a valid longitude (-180 <= x <= 180).', + (string)$rule->validate('1230'), + ); + isSame( + '"is_longitude" at line 0, column "prop". ' . + 'Value "180.0001" is not a valid longitude (-180 <= x <= 180).', + (string)$rule->validate('180.0001'), + ); + isSame( + '"is_longitude" at line 0, column "prop". Value "-180.1" is not a valid longitude (-180 <= x <= 180).', + (string)$rule->validate('-180.1'), + ); + isSame( + '"is_longitude" at line 0, column "prop". Value "1.0.0.0" is not a float number.', + (string)$rule->validate('1.0.0.0'), + ); + } + + public function testIsUrl(): void + { + $rule = new IsUrl('prop', true); + isSame(null, $rule->validate('http://example.com')); + isSame(null, $rule->validate('http://example.com/home-page')); + isSame(null, $rule->validate('ftp://user:pass@example.com/home-page?param=value&v=asd#anchor')); + isSame( + '"is_url" at line 0, column "prop". Value "123" is not a valid URL.', + (string)$rule->validate('123'), + ); + isSame( + '"is_url" at line 0, column "prop". Value "//example.com" is not a valid URL.', + (string)$rule->validate('//example.com'), + ); + } + + public function testMin(): void + { + $rule = new Min('prop', 10); + isSame(null, $rule->validate('10')); + isSame(null, $rule->validate('11')); + isSame( + '"min" at line 0, column "prop". Value "9" is less than "10".', + (string)$rule->validate('9'), + ); + isSame( + '"min" at line 0, column "prop". Value "example.com" is not a float number.', + (string)$rule->validate('example.com'), + ); + + $rule = new Min('prop', 10.1); + isSame(null, $rule->validate('10.1')); + isSame(null, $rule->validate('11')); + isSame( + '"min" at line 0, column "prop". Value "9" is less than "10.1".', + (string)$rule->validate('9'), + ); + isSame( + '"min" at line 0, column "prop". Value "example.com" is not a float number.', + (string)$rule->validate('example.com'), + ); + } + + public function testMax(): void + { + $rule = new Max('prop', 10); + isSame(null, $rule->validate('9')); + isSame(null, $rule->validate('10')); + isSame( + '"max" at line 0, column "prop". Value "123" is greater than "10".', + (string)$rule->validate('123'), + ); + isSame( + '"max" at line 0, column "prop". Value "example.com" is not a float number.', + (string)$rule->validate('example.com'), + ); + + $rule = new Max('prop', 10.1); + isSame(null, $rule->validate('9')); + isSame(null, $rule->validate('10.0')); + isSame(null, $rule->validate('10.1')); + isSame( + '"max" at line 0, column "prop". Value "10.2" is greater than "10.1".', + (string)$rule->validate('10.2'), + ); + } + + public function testMinDate(): void + { + $rule = new MinDate('prop', '2000-01-10'); + isSame(null, $rule->validate('2000-01-10')); + isSame( + '"min_date" at line 0, column "prop". ' . + 'Value "2000-01-09" is less than the minimum date "2000-01-10T00:00:00.000+00:00".', + (string)$rule->validate('2000-01-09'), + ); + + $rule = new MinDate('prop', '2000-01-10 00:00:00 +01:00'); + isSame(null, $rule->validate('2000-01-10 00:00:00 +01:00')); + isSame( + '"min_date" at line 0, column "prop". ' . + 'Value "2000-01-09 23:59:59 Europe/Berlin" is less than the minimum date "2000-01-10T00:00:00.000+01:00".', + (string)$rule->validate('2000-01-09 23:59:59 Europe/Berlin'), + ); + + $rule = new MinDate('prop', '-1000 years'); + isSame(null, $rule->validate('2000-01-10 00:00:00 +01:00')); + } + + public function testMaxDate(): void + { + $rule = new MaxDate('prop', '2000-01-10'); + isSame(null, $rule->validate('2000-01-09')); + isSame( + '"max_date" at line 0, column "prop". ' . + 'Value "2000-01-11" is more than the maximum date "2000-01-10T00:00:00.000+00:00".', + (string)$rule->validate('2000-01-11'), + ); + + $rule = new MaxDate('prop', '2000-01-10 00:00:00'); + isSame(null, $rule->validate('2000-01-10 00:00:00')); + isSame( + '"max_date" at line 0, column "prop". ' . + 'Value "2000-01-10 00:00:01" is more than the maximum date "2000-01-10T00:00:00.000+00:00".', + (string)$rule->validate('2000-01-10 00:00:01'), + ); + + $rule = new MaxDate('prop', '+1 day'); + isSame(null, $rule->validate('2000-01-10 00:00:00 +01:00')); + } + + public function testMinLength(): void + { + $rule = new MinLength('prop', 5); + isSame(null, $rule->validate('12345')); + isSame(null, $rule->validate(' ')); + isSame(null, $rule->validate(' 1 ')); + isSame( + '"min_length" at line 0, column "prop". Value "1234" (legth: 4) is too short. Min length is 5.', + (string)$rule->validate('1234'), + ); + isSame( + '"min_length" at line 0, column "prop". Value "123 " (legth: 4) is too short. Min length is 5.', + (string)$rule->validate('123 '), + ); + isSame( + '"min_length" at line 0, column "prop". Value "" (legth: 0) is too short. Min length is 5.', + (string)$rule->validate(''), + ); + } + + public function testMaxLength(): void + { + $rule = new MaxLength('prop', 5); + isSame(null, $rule->validate('')); + isSame(null, $rule->validate('1234')); + isSame(null, $rule->validate('12345')); + isSame(null, $rule->validate(' ')); + isSame(null, $rule->validate(' 1 ')); + isSame( + '"max_length" at line 0, column "prop". Value "123456" (legth: 6) is too long. Max length is 5.', + (string)$rule->validate('123456'), + ); + isSame( + '"max_length" at line 0, column "prop". Value "12345 " (legth: 6) is too long. Max length is 5.', + (string)$rule->validate('12345 '), + ); + } + + public function testNotEmpty(): void + { + $rule = new NotEmpty('prop', true); + isSame(null, $rule->validate('0')); + isSame(null, $rule->validate('false')); + isSame(null, $rule->validate('1')); + isSame(null, $rule->validate(' 0')); + isSame(null, $rule->validate(' ')); + isSame( + '"not_empty" at line 0, column "prop". Value is empty.', + (string)$rule->validate(''), + ); + isSame( + '"not_empty" at line 0, column "prop". Value is empty.', + (string)$rule->validate(null), + ); + } + + public function testOnlyCapitalize(): void + { + $rule = new OnlyCapitalize('prop', true); + isSame(null, $rule->validate('0')); + isSame(null, $rule->validate('False')); + isSame(null, $rule->validate('Qwe Rty')); + isSame(null, $rule->validate(' Qwe Rty')); + isSame(null, $rule->validate(' ')); + isSame( + '"only_capitalize" at line 0, column "prop". Value "qwerty" should be in capitalize.', + (string)$rule->validate('qwerty'), + ); + isSame( + '"only_capitalize" at line 0, column "prop". Value "qwe Rty" should be in capitalize.', + (string)$rule->validate('qwe Rty'), + ); + } + + public function testOnlyLowercase(): void + { + $rule = new OnlyLowercase('prop', true); + isSame(null, $rule->validate('0')); + isSame(null, $rule->validate('false')); + isSame(null, $rule->validate('qwe rty')); + isSame(null, $rule->validate(' qwe rty')); + isSame(null, $rule->validate(' ')); + isSame( + '"only_lowercase" at line 0, column "prop". Value "Qwerty" should be in lowercase.', + (string)$rule->validate('Qwerty'), + ); + isSame( + '"only_lowercase" at line 0, column "prop". Value "qwe Rty" should be in lowercase.', + (string)$rule->validate('qwe Rty'), + ); + } + + public function testOnlyUppercase(): void + { + $rule = new OnlyUppercase('prop', true); + isSame(null, $rule->validate('0')); + isSame(null, $rule->validate('FALSE')); + isSame(null, $rule->validate('QWE RTY')); + isSame(null, $rule->validate(' ')); + isSame( + '"only_uppercase" at line 0, column "prop". Value "Qwerty" is not uppercase.', + (string)$rule->validate('Qwerty'), + ); + isSame( + '"only_uppercase" at line 0, column "prop". Value "qwe Rty" is not uppercase.', + (string)$rule->validate('qwe Rty'), + ); + } + + public function testPrecision(): void + { + $rule = new Precision('prop', 0); + isSame(null, $rule->validate('0')); + isSame(null, $rule->validate('10')); + isSame(null, $rule->validate('-10')); + isSame( + '"precision" at line 0, column "prop". ' . + 'Value "1.1" has a precision of 1 but should have a precision of 0.', + (string)$rule->validate('1.1'), + ); + isSame( + '"precision" at line 0, column "prop". ' . + 'Value "1.0" has a precision of 1 but should have a precision of 0.', + (string)$rule->validate('1.0'), + ); + + $rule = new Precision('prop', 1); + isSame(null, $rule->validate('0.0')); + isSame(null, $rule->validate('10.0')); + isSame(null, $rule->validate('-10.0')); + isSame( + '"precision" at line 0, column "prop". ' . + 'Value "1" has a precision of 0 but should have a precision of 1.', + (string)$rule->validate('1'), + ); + isSame( + '"precision" at line 0, column "prop". ' . + 'Value "1.01" has a precision of 2 but should have a precision of 1.', + (string)$rule->validate('1.01'), + ); + + $rule = new Precision('prop', 2); + isSame(null, $rule->validate('0.01')); + isSame(null, $rule->validate('10.00')); + isSame(null, $rule->validate('-10.00')); + isSame( + '"precision" at line 0, column "prop". ' . + 'Value "2.0" has a precision of 1 but should have a precision of 2.', + (string)$rule->validate('2.0'), + ); + isSame( + '"precision" at line 0, column "prop". ' . + 'Value "1.000" has a precision of 3 but should have a precision of 2.', + (string)$rule->validate('1.000'), + ); + } + + public function testRegex(): void + { + $rule = new Regex('prop', '/^a/'); + isSame(null, $rule->validate('abc')); + isSame(null, $rule->validate('aaa')); + isSame(null, $rule->validate('a')); + isSame( + '"regex" at line 0, column "prop". Value "1bc" does not match the pattern "/^a/".', + (string)$rule->validate('1bc'), + ); + + $rule = new Regex('prop', '^a'); + isSame(null, $rule->validate('abc')); + isSame(null, $rule->validate('aaa')); + isSame(null, $rule->validate('a')); + isSame( + '"regex" at line 0, column "prop". Value "1bc" does not match the pattern "/^a/u".', + (string)$rule->validate('1bc'), + ); + } + + public function testUnitFacing(): void + { + $rule = new CardinalDirection('prop', true); + isSame(null, $rule->validate('N')); + isSame(null, $rule->validate('S')); + isSame(null, $rule->validate('E')); + isSame(null, $rule->validate('W')); + isSame(null, $rule->validate('NE')); + isSame(null, $rule->validate('SE')); + isSame(null, $rule->validate('NW')); + isSame(null, $rule->validate('SW')); + isSame(null, $rule->validate('none')); + isSame( + '"cardinal_direction" at line 0, column "prop". Value "qwe" is not allowed. ' . + 'Allowed values: ["N", "S", "E", "W", "NE", "SE", "NW", "SW", "none", ""].', + (string)$rule->validate('qwe'), + ); + } + + public function testUsaMarketName(): void + { + $rule = new UsaMarketName('prop', true); + isSame(null, $rule->validate('New York, NY')); + isSame(null, $rule->validate('City, ST')); + isSame( + '"usa_market_name" at line 0, column "prop". ' . + 'Invalid market name format for value ", ST". ' . + 'Market name must have format "New York, NY".', + (string)$rule->validate(', ST'), + ); + } + + public function testIsUuid4(): void + { + $rule = new IsUuid4('prop', true); + isSame(null, $rule->validate(Str::uuid())); + isSame( + '"is_uuid4" at line 0, column "prop". Value is not a valid UUID v4.', + (string)$rule->validate('123'), + ); + } +} diff --git a/tests/Blueprint/SchemaTest.php b/tests/Blueprint/SchemaTest.php new file mode 100644 index 00000000..aea2416a --- /dev/null +++ b/tests/Blueprint/SchemaTest.php @@ -0,0 +1,233 @@ +getFilename()); + + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL); + isSame(self::SCHEMA_EXAMPLE_FULL, $schemaFull->getFilename()); + } + + public function testGetFinenamePattern(): void + { + $schemaEmpty = new Schema(self::SCHEMA_EXAMPLE_EMPTY); + isSame(null, $schemaEmpty->getFinenamePattern()); + + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL); + isSame('^example\.csv$', $schemaFull->getFinenamePattern()); + } + + public function testScvStruture(): void + { + $schemaEmpty = new Schema(self::SCHEMA_EXAMPLE_EMPTY); + isSame([ + // 'inherit' => null, + 'header' => true, + 'delimiter' => ',', + 'quote_char' => '\\', + 'enclosure' => '"', + 'encoding' => 'utf-8', + 'bom' => false, + // 'strict_column_order' => false, + // 'other_columns_possible' => false, + ], $schemaEmpty->getCsvStructure()->getArrayCopy()); + + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL); + isSame([ + // 'inherit' => 'alias_1', + 'header' => true, + 'delimiter' => ',', + 'quote_char' => '\\', + 'enclosure' => '"', + 'encoding' => 'utf-8', + 'bom' => false, + // 'strict_column_order' => true, + // 'other_columns_possible' => true, + ], $schemaFull->getCsvStructure()->getArrayCopy()); + } + + public function testColumns(): void + { + $schemaEmpty = new Schema(self::SCHEMA_EXAMPLE_EMPTY); + isSame([], $schemaEmpty->getColumns()); + + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL); + isSame([ + 0 => 0, + 1 => 'General available options', + 2 => 'Some String', + 3 => 'Some Integer', + 4 => 'Some Float', + 5 => 'Some Date', + 6 => 'Some Enum', + 7 => 'Some Boolean', + 8 => 'Some Inherited', + 9 => 'Some Latitude', + 10 => 'Some Longitude', + 11 => 'Some URL', + 12 => 'Some Email', + 13 => 'Some IP', + 14 => 'Some UUID', + 15 => 'Some Custom Rule', + ], \array_keys($schemaFull->getColumns())); + } + + public function testColumnByNameAndId(): void + { + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL); + isNotNull($schemaFull->getColumn(1)); + isNotNull($schemaFull->getColumn('General available options')); + + isSame( + $schemaFull->getColumn(1), + $schemaFull->getColumn('General available options'), + ); + } + + public function testIncludes(): void + { + $schemaEmpty = new Schema(self::SCHEMA_EXAMPLE_EMPTY); + isSame([], $schemaEmpty->getIncludes()); + + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL); + isSame([ + 'alias_1' => '/path/schema_1.yml', + 'alias_2' => './path/schema_2.yml', + 'alias_3' => '../path/schema_3.yml', + ], $schemaFull->getIncludes()); + } + + public function testGetUndefinedColumnById(): void + { + $this->expectExceptionMessage( + 'Column "1000" not found in schema "' . self::SCHEMA_EXAMPLE_EMPTY . '"', + ); + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_EMPTY); + isNull($schemaFull->getColumn(1000)); + } + + public function testGetUndefinedColumnByName(): void + { + $this->expectExceptionMessage( + 'Column "undefined_column" not found in schema "' . self::SCHEMA_EXAMPLE_EMPTY . '"', + ); + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_EMPTY); + isNull($schemaFull->getColumn('undefined_column')); + } + + public function testGetColumnMinimal(): void + { + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL); + $column = $schemaFull->getColumn(0); + + isSame('', $column->getName()); + isSame('', $column->getDescription()); + isSame('base', $column->getType()); + isSame(null, $column->getRegex()); + isSame('', $column->getInherit()); + isFalse($column->isRequired()); + + isTrue(\is_array($column->getRules())); + isEmpty($column->getRules()); + + isTrue(\is_array($column->getAggregateRules())); + isEmpty($column->getAggregateRules()); + } + + public function testGetColumnProps(): void + { + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL); + $column = $schemaFull->getColumn(1); + + isSame('General available options', $column->getName()); + isSame('Some description', $column->getDescription()); + isSame('some_type', $column->getType()); + isSame('', $column->getInherit()); + + isTrue($column->isRequired()); + + isTrue(\is_array($column->getRules())); + isNotEmpty($column->getRules()); + + isTrue(\is_array($column->getAggregateRules())); + isNotEmpty($column->getAggregateRules()); + } + + public function testGetColumnRules(): void + { + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL); + $column = $schemaFull->getColumn('Some String'); + + isSame([ + 'min_length' => 1, + 'max_length' => 10, + 'only_trimed' => false, + 'only_uppercase' => false, + 'only_lowercase' => false, + 'only_capitalize' => false, + ], $column->getRules()); + } + + public function testGetColumnAggregateRules(): void + { + $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL); + $column = $schemaFull->getColumn(1); + + isSame([ + 'unique' => false, + 'sorted' => 'asc', + 'sorted_flag' => 'SORT_NATURAL', + 'count_min' => 1, + 'count_max' => 10, + 'count_empty_min' => 1, + 'count_empty_max' => 10, + 'count_filled_min' => 1, + 'count_filled_max' => 10, + 'custom_1' => [ + 'class' => 'My\\Aggregate\\Rules1', + 'args' => ['value'], + ], + 'custom_2' => [ + 'class' => 'My\\Aggregate\\Rules2', + 'args' => ['value1', 'value2'], + ], + 'custom_my_favorite_name' => [ + 'class' => 'My\\Aggregate\\RulesXXX', + 'args' => [], + ], + ], $column->getAggregateRules()); + } +} diff --git a/tests/Blueprint/ValidatorTest.php b/tests/Blueprint/ValidatorTest.php new file mode 100644 index 00000000..8846c892 --- /dev/null +++ b/tests/Blueprint/ValidatorTest.php @@ -0,0 +1,367 @@ +expectExceptionMessage( + 'Rule "undefined_rule" not found. Expected class: "JBZoo\CsvBlueprint\Validators\Rules\UndefinedRule"', + ); + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'undefined_rule', true)); + $csv->validate(); + } + + public function testValidWithHeader(): void + { + $csv = new CsvFile(self::CSV_SIMPLE_HEADER, self::SCHEMA_SIMPLE_HEADER); + isSame('', (string)$csv->validate()); + } + + public function testValidWithoutHeader(): void + { + $csv = new CsvFile(self::CSV_SIMPLE_NO_HEADER, self::SCHEMA_SIMPLE_NO_HEADER); + isSame('', (string)$csv->validate()); + } + + public function testNotEmptyMessage(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'not_empty', true)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('integer', 'not_empty', true)); + isSame( + '"not_empty" at line 19, column "0:integer". Value is empty.', + (string)$csv->validate(), + ); + } + + public function testNoName(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule(null, 'not_empty', true)); + isSame( + '"csv.header" at line 1, column "0:". ' . + 'Property "name" is not defined in schema: "_custom_array_".', + (string)$csv->validate(), + ); + } + + public function testMin(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'min', -10)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'min', 10)); + isSame( + '"min" at line 2, column "0:seq". Value "1" is less than "10".', + (string)$csv->validate()->get(0), + ); + } + + public function testMax(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'max', 10000)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'max', 10)); + isSame( + '"max" at line 12, column "0:seq". Value "11" is greater than "10".', + (string)$csv->validate()->get(0), + ); + } + + public function testRegex(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'regex', '.*')); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'regex', '^[a-zA-Z0-9]+$')); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'regex', '[a-z]')); + isSame( + '"regex" at line 2, column "0:seq". Value "1" does not match the pattern "/[a-z]/u".', + (string)$csv->validate()->get(0), + ); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'regex', '/[a-z]/')); + isSame( + '"regex" at line 2, column "0:seq". Value "1" does not match the pattern "/[a-z]/".', + (string)$csv->validate()->get(0), + ); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'regex', '/[a-z]/i')); + isSame( + '"regex" at line 2, column "0:seq". Value "1" does not match the pattern "/[a-z]/i".', + (string)$csv->validate()->get(0), + ); + } + + public function testMinLength(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'min_length', 1)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'min_length', 1000)); + isSame( + '"min_length" at line 2, column "0:seq". Value "1" (legth: 1) is too short. Min length is 1000.', + (string)$csv->validate()->get(0), + ); + } + + public function testMaxLength(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'max_length', 10)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'max_length', 1)); + isSame( + '"max_length" at line 11, column "0:seq". Value "10" (legth: 2) is too long. Max length is 1.', + (string)$csv->validate()->get(0), + ); + } + + public function testOnlyTrimed(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'only_trimed', true)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('sentence', 'only_trimed', true)); + isSame( + '"only_trimed" at line 14, column "0:sentence". Value " Urecam" is not trimmed.', + (string)$csv->validate()->get(0), + ); + } + + public function testOnlyUppercase(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'only_uppercase', true)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'only_uppercase', true)); + isSame( + '"only_uppercase" at line 2, column "0:bool". Value "true" is not uppercase.', + (string)$csv->validate()->get(0), + ); + } + + public function testOnlyLowercase(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'only_lowercase', true)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'only_lowercase', true)); + isSame( + '"only_lowercase" at line 8, column "0:bool". Value "False" should be in lowercase.', + (string)$csv->validate()->get(0), + ); + } + + public function testOnlyCapitalize(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'only_capitalize', true)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'only_capitalize', true)); + isSame( + '"only_capitalize" at line 2, column "0:bool". Value "true" should be in capitalize.', + (string)$csv->validate()->get(0), + ); + } + + public function testPrecision(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'precision', 0)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'precision', 1)); + isSame( + '"precision" at line 2, column "0:seq". ' . + 'Value "1" has a precision of 0 but should have a precision of 1.', + (string)$csv->validate()->get(0), + ); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('float', 'precision', 3)); + isSame( + '"precision" at line 3, column "0:float". ' . + 'Value "506847750940.2624" has a precision of 4 but should have a precision of 3.', + (string)$csv->validate()->get(0), + ); + } + + public function testMinDate(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'min_date', '2000-01-01')); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'min_date', '2120-01-01')); + isSame( + '"min_date" at line 2, column "0:date". ' . + 'Value "2042/11/18" is less than the minimum date "2120-01-01T00:00:00.000+00:00".', + (string)$csv->validate()->get(0), + ); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'min_date', '2042/11/17')); + isSame( + '"min_date" at line 5, column "0:date". ' . + 'Value "2032/09/09" is less than the minimum date "2042-11-17T00:00:00.000+00:00".', + (string)$csv->validate()->get(0), + ); + } + + public function testMaxDate(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'max_date', '2200-01-01')); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'max_date', '2120-01-01')); + isSame( + '"max_date" at line 23, column "0:date". ' . + 'Value "2120/02/01" is more than the maximum date "2120-01-01T00:00:00.000+00:00".', + (string)$csv->validate()->get(0), + ); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'max_date', '2042/11/17')); + isSame( + '"max_date" at line 2, column "0:date". ' . + 'Value "2042/11/18" is more than the maximum date "2042-11-17T00:00:00.000+00:00".', + (string)$csv->validate()->get(0), + ); + } + + public function testDateFormat(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'date_format', 'Y/m/d')); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'date_format', 'Y/m/d H:i:s')); + isSame( + '"date_format" at line 2, column "0:date". ' . + 'Date format of value "2042/11/18" is not valid. Expected format: "Y/m/d H:i:s".', + (string)$csv->validate()->get(0), + ); + } + + public function testAllowValues(): void + { + $csv = new CsvFile( + self::CSV_COMPLEX, + $this->getRule( + 'bool', + 'allow_values', + ['true', 'false', 'False', 'True'], + ), + ); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'allow_values', ['true', 'false'])); + isSame( + '"allow_values" at line 8, column "0:bool". ' . + 'Value "False" is not allowed. Allowed values: ["true", "false"].', + (string)$csv->validate()->get(0), + ); + } + + public function testExactValue(): void + { + $csv = new CsvFile(self::CSV_SIMPLE_HEADER, $this->getRule('exact', 'exact_value', '1')); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_SIMPLE_HEADER, $this->getRule('exact', 'exact_value', '2')); + isSame( + '"exact_value" at line 2, column "0:exact". Value "1" is not strict equal to "2".', + (string)$csv->validate()->get(0), + ); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'exact_value', 'true')); + isSame( + '"exact_value" at line 4, column "0:bool". Value "false" is not strict equal to "true".', + (string)$csv->validate()->get(0), + ); + } + + public function testIsInt(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'is_int', true)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'is_int', true)); + isSame( + '"is_int" at line 2, column "0:bool". Value "true" is not an integer.', + (string)$csv->validate()->get(0), + ); + } + + public function testIsFloat(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'is_float', true)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'is_float', true)); + isSame( + '"is_float" at line 2, column "0:bool". Value "true" is not a float number.', + (string)$csv->validate()->get(0), + ); + } + + public function testIsBool(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'is_bool', true)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('yn', 'is_bool', true)); + isSame( + '"is_bool" at line 2, column "0:yn". Value "n" is not allowed. Allowed values: ["true", "false"].', + (string)$csv->validate()->get(0), + ); + } + + public function testIsEmail(): void + { + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('email', 'is_email', true)); + isSame('', (string)$csv->validate()); + + $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('yn', 'is_email', true)); + isSame( + '"is_email" at line 2, column "0:yn". Value "N" is not a valid email.', + (string)$csv->validate()->get(0), + ); + } + + private function getRule(?string $columnName, ?string $ruleName, array|bool|float|int|string $options): array + { + return ['columns' => [['name' => $columnName, 'rules' => [$ruleName => $options]]]]; + } +} diff --git a/tests/CsvBlueprintPackageTest.php b/tests/CsvBlueprintPackageTest.php new file mode 100644 index 00000000..e88aca12 --- /dev/null +++ b/tests/CsvBlueprintPackageTest.php @@ -0,0 +1,22 @@ +