From 3aba1fa564a050c490fe52f422998b32d63dd982 Mon Sep 17 00:00:00 2001 From: Florian Guimier Date: Fri, 20 Dec 2024 15:09:32 +0100 Subject: [PATCH 1/3] Revert "Revert "Add SF7 support"" This reverts commit cf63bbb3394f37badb508c2e6a97296a6cf53a12. --- .github/workflows/build.yml | 58 + .github/workflows/php_lint.yml | 14 - .github/workflows/phpunit.yml | 31 - .github/workflows/symfony.yml | 37 - .gitignore | 5 +- .php-cs-fixer.dist.php | 60 - .php-cs-fixer.php-highest.php | 20 - README.md | 8 +- composer.json | 30 +- composer.lock | 3116 -------------------------------- phpcs.xml.dist | 10 + phpstan.neon | 5 +- src/ExcelEncoder.php | 146 +- tests.phpstan.neon | 6 - tests/ExcelEncoderTest.php | 166 +- 15 files changed, 264 insertions(+), 3448 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/php_lint.yml delete mode 100644 .github/workflows/phpunit.yml delete mode 100644 .github/workflows/symfony.yml delete mode 100644 .php-cs-fixer.dist.php delete mode 100644 .php-cs-fixer.php-highest.php delete mode 100644 composer.lock create mode 100644 phpcs.xml.dist delete mode 100755 tests.phpstan.neon diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..83185a2 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,58 @@ +name: Build + +on: + push: + branches: [ master ] + pull_request: + types: [opened, synchronize, reopened] + +jobs: + build: + strategy: + fail-fast: false + matrix: + php-versions: ['8.3'] + dependency-versions: ['lowest', 'highest'] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + + - run: composer validate --strict + + - uses: ramsey/composer-install@v2 + with: + dependency-versions: ${{ matrix.dependency-versions }} + + - run: vendor/bin/phpcs + if: ${{ failure() || success() }} + + - run: vendor/bin/phpstan + if: ${{ failure() || success() }} + + - run: XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-clover ./clover.xml --log-junit ./phpunit.report.xml + if: ${{ failure() || success() }} + + # https://community.sonarsource.com/t/code-coverage-doesnt-work-with-github-action/16747 + # $GITHUB_WORKSPACE contains a slash so @ is used as delimiter + - run: sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' clover.xml + - run: sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' phpunit.report.xml + + - uses: sonarsource/sonarcloud-github-action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: > + -Dsonar.projectName=[your-repo] + -Dsonar.projectKey=assoconnect_[your-repo] + -Dsonar.organization=assoconnect + -Dsonar.sources=src + -Dsonar.tests=tests + -Dsonar.php.coverage.reportPaths=clover.xml + -Dsonar.php.tests.reportPath=phpunit.report.xml diff --git a/.github/workflows/php_lint.yml b/.github/workflows/php_lint.yml deleted file mode 100644 index 8e614e9..0000000 --- a/.github/workflows/php_lint.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: PHP Linting - -on: [push, pull_request] - -jobs: - php-cs-fixer: - name: PHP-CS-Fixer - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: PHP-CS-Fixer - uses: docker://oskarstark/php-cs-fixer-ga - with: - args: src --diff --dry-run --config=.php-cs-fixer.php-highest.php \ No newline at end of file diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml deleted file mode 100644 index a33f6b3..0000000 --- a/.github/workflows/phpunit.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: PHPUnit tests - -on: [push, pull_request] - -permissions: - contents: read - -jobs: - tests_suite: - strategy: - matrix: - php_version: [ '8.1', '8.2' ] - runs-on: ubuntu-latest - steps: - - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php_version }} - - uses: actions/checkout@v3 - - name: Cache Composer packages - id: composer-cache - uses: actions/cache@v3 - with: - path: vendor - key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-php- - - name: Install Dependencies - run: | - composer install - - name: Execute PHPUnit tests - run: vendor/bin/phpunit diff --git a/.github/workflows/symfony.yml b/.github/workflows/symfony.yml deleted file mode 100644 index b42f782..0000000 --- a/.github/workflows/symfony.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Symfony - -on: [push, pull_request] - -permissions: - contents: read - -jobs: - install: - strategy: - matrix: - php_version: [ '8.1', '8.2' ] - symfony_version: [ '6.0', '6.1', '6.2' ] - runs-on: ubuntu-latest - steps: - - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php_version }} - #extensions: dom, curl, libxml, mbstring - - uses: actions/checkout@v3 - - name: Create new project - run: | - mkdir component - shopt -s extglob dotglob - mv !(component) component - composer create-project symfony/skeleton:"${{ matrix.symfony_version }}.*" app - - name: Component installation - run: | - cd app - composer config repositories.component path "../component" - composer config minimum-stability dev - composer require ang3/php-excel-encoder "*" - cd .. - - name: Clear cache - run: | - cd app - php bin/console cache:clear diff --git a/.gitignore b/.gitignore index cf8035b..161277c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ /bin/ /vendor/ +.idea/ +.idea .php_cs.cache .php-cs-fixer.cache .phpunit.result.cache -test.php -.idea/ \ No newline at end of file +test.php \ No newline at end of file diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php deleted file mode 100644 index 16cf13d..0000000 --- a/.php-cs-fixer.dist.php +++ /dev/null @@ -1,60 +0,0 @@ -ignoreDotFiles(false) - ->ignoreVCSIgnored(true) - ->exclude('tests/Fixtures') - ->in(__DIR__) - ->append([ - __DIR__.'/dev-tools/doc.php', - // __DIR__.'/php-cs-fixer', disabled, as we want to be able to run bootstrap file even on lower PHP version, to show nice message - ]) -; - -$config = new PhpCsFixer\Config(); -$config - ->setRiskyAllowed(true) - ->setRules([ - '@PHP74Migration' => true, - '@PHP74Migration:risky' => true, - '@PHPUnit100Migration:risky' => true, - '@PhpCsFixer' => true, - '@PhpCsFixer:risky' => true, - '@Symfony' => true, - 'general_phpdoc_annotation_remove' => ['annotations' => ['expectedDeprecation']], // one should use PHPUnit built-in method instead - 'header_comment' => ['header' => $header], - 'heredoc_indentation' => false, // TODO switch on when # of PR's is lower - 'modernize_strpos' => true, // needs PHP 8+ or polyfill - 'no_useless_concat_operator' => false, // TODO switch back on when the `src/Console/Application.php` no longer needs the concat - 'use_arrow_functions' => false, // TODO switch on when # of PR's is lower - ]) - ->setFinder($finder) -; - -// special handling of fabbot.io service if it's using too old PHP CS Fixer version -if (false !== getenv('FABBOT_IO')) { - try { - PhpCsFixer\FixerFactory::create() - ->registerBuiltInFixers() - ->registerCustomFixers($config->getCustomFixers()) - ->useRuleSet(new PhpCsFixer\RuleSet($config->getRules())) - ; - } catch (PhpCsFixer\ConfigurationException\InvalidConfigurationException $e) { - $config->setRules([]); - } catch (UnexpectedValueException $e) { - $config->setRules([]); - } catch (InvalidArgumentException $e) { - $config->setRules([]); - } -} - -return $config; diff --git a/.php-cs-fixer.php-highest.php b/.php-cs-fixer.php-highest.php deleted file mode 100644 index db24d09..0000000 --- a/.php-cs-fixer.php-highest.php +++ /dev/null @@ -1,20 +0,0 @@ -= 80200) { - fwrite(STDERR, "PHP CS Fixer's config for PHP-HIGHEST can be executed only on highest supported PHP version - 8.1.*.\n"); - fwrite(STDERR, "Running it on lower PHP version would prevent calling migration rules.\n"); - - exit(1); -} - -$config = require __DIR__.'/.php-cs-fixer.dist.php'; - -$config->setRules(array_merge($config->getRules(), [ - '@PHP81Migration' => true, - '@PHP80Migration:risky' => true, - 'heredoc_indentation' => false, -])); - -return $config; diff --git a/README.md b/README.md index ceef0a1..9e59ce5 100755 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Installation Open a command console and execute the following command to download the latest stable version of this bundle: ```shell -composer require ang3/php-excel-encoder +composer require assoconnect/php-excel-encoder ``` If you install this component outside of a Symfony application, you must require the vendor/autoload.php @@ -52,7 +52,7 @@ Usage require_once 'vendor/autoload.php'; -use Ang3\Component\Serializer\Encoder\ExcelEncoder; +use assoconnect\Serializer\Encoder\ExcelEncoder; // Create the encoder with default context $encoder = new ExcelEncoder($defaultContext = []); @@ -212,13 +212,13 @@ configure it as service by adding the contents below into the file `config/servi # config/services.yaml services: # ... - Ang3\Component\Serializer\Encoder\ExcelEncoder: ~ + AssoConnect\Serializer\Encoder\ExcelEncoder: ~ ``` Run tests --------- -```$ git clone https://github.com/Ang3/php-excel-encoder.git``` +```$ git clone https://github.com/assoconnect/php-excel-encoder.git``` ```$ composer install``` diff --git a/composer.json b/composer.json index 48c7d1b..25964c7 100755 --- a/composer.json +++ b/composer.json @@ -1,32 +1,42 @@ { - "name": "ang3/php-excel-encoder", + "name": "assoconnect/php-excel-encoder", "type": "library", - "homepage": "https://github.com/Ang3/php-excel-encoder", + "homepage": "https://github.com/assoconnect/php-excel-encoder", "description": "PHP Excel encoder", "license": "MIT", "authors": [ { "name": "Joanis ROUANET", "email": "joanis.ang3@gmail.com" + }, + { + "name": "Florian GUIMIER", + "email": "florian.guimier@gmail.com" } ], "autoload": { "psr-4": { - "Ang3\\Component\\Serializer\\Encoder\\": "src/" + "AssoConnect\\Serializer\\Encoder\\": "src/" } }, "autoload-dev": { "psr-4": { - "Ang3\\Component\\Serializer\\Encoder\\Tests\\": "tests/" + "AssoConnect\\Serializer\\Encoder\\Tests\\": "tests/" } }, "require": { - "php": ">=8.1", + "php": "^8.2", "phpoffice/phpspreadsheet": "^1.16|^2.0", - "symfony/serializer": "^6.0", - "symfony/filesystem": "^6.0" - }, - "require-dev": { - "symfony/test-pack": "^1.0" + "symfony/serializer": "^6.0|^7.0", + "symfony/filesystem": "^6.0|^7.0" + }, + "require-dev": { + "symfony/test-pack": "^1.0", + "assoconnect/php-quality-config": "^1.13" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } } } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 0c4815d..0000000 --- a/composer.lock +++ /dev/null @@ -1,3116 +0,0 @@ -{ - "_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": "a76d1be06f320b6c61d0a6296a2e2bdf", - "packages": [ - { - "name": "ezyang/htmlpurifier", - "version": "v4.16.0", - "source": { - "type": "git", - "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/523407fb06eb9e5f3d59889b3978d5bfe94299c8", - "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8", - "shasum": "" - }, - "require": { - "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0" - }, - "require-dev": { - "cerdic/css-tidy": "^1.7 || ^2.0", - "simpletest/simpletest": "dev-master" - }, - "suggest": { - "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", - "ext-bcmath": "Used for unit conversion and imagecrash protection", - "ext-iconv": "Converts text to and from non-UTF-8 encodings", - "ext-tidy": "Used for pretty-printing HTML" - }, - "type": "library", - "autoload": { - "files": [ - "library/HTMLPurifier.composer.php" - ], - "psr-0": { - "HTMLPurifier": "library/" - }, - "exclude-from-classmap": [ - "/library/HTMLPurifier/Language/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Edward Z. Yang", - "email": "admin@htmlpurifier.org", - "homepage": "http://ezyang.com" - } - ], - "description": "Standards compliant HTML filter written in PHP", - "homepage": "http://htmlpurifier.org/", - "keywords": [ - "html" - ], - "support": { - "issues": "https://github.com/ezyang/htmlpurifier/issues", - "source": "https://github.com/ezyang/htmlpurifier/tree/v4.16.0" - }, - "time": "2022-09-18T07:06:19+00:00" - }, - { - "name": "maennchen/zipstream-php", - "version": "v2.4.0", - "source": { - "type": "git", - "url": "https://github.com/maennchen/ZipStream-PHP.git", - "reference": "3fa72e4c71a43f9e9118752a5c90e476a8dc9eb3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/3fa72e4c71a43f9e9118752a5c90e476a8dc9eb3", - "reference": "3fa72e4c71a43f9e9118752a5c90e476a8dc9eb3", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "myclabs/php-enum": "^1.5", - "php": "^8.0", - "psr/http-message": "^1.0" - }, - "require-dev": { - "ext-zip": "*", - "friendsofphp/php-cs-fixer": "^3.9", - "guzzlehttp/guzzle": "^6.5.3 || ^7.2.0", - "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.4", - "phpunit/phpunit": "^8.5.8 || ^9.4.2", - "vimeo/psalm": "^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "ZipStream\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paul Duncan", - "email": "pabs@pablotron.org" - }, - { - "name": "Jonatan Männchen", - "email": "jonatan@maennchen.ch" - }, - { - "name": "Jesse Donat", - "email": "donatj@gmail.com" - }, - { - "name": "András Kolesár", - "email": "kolesar@kolesar.hu" - } - ], - "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", - "keywords": [ - "stream", - "zip" - ], - "support": { - "issues": "https://github.com/maennchen/ZipStream-PHP/issues", - "source": "https://github.com/maennchen/ZipStream-PHP/tree/v2.4.0" - }, - "funding": [ - { - "url": "https://github.com/maennchen", - "type": "github" - }, - { - "url": "https://opencollective.com/zipstream", - "type": "open_collective" - } - ], - "time": "2022-12-08T12:29:14+00:00" - }, - { - "name": "markbaker/complex", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/MarkBaker/PHPComplex.git", - "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9", - "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "dev-master", - "phpcompatibility/php-compatibility": "^9.3", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", - "squizlabs/php_codesniffer": "^3.7" - }, - "type": "library", - "autoload": { - "psr-4": { - "Complex\\": "classes/src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mark Baker", - "email": "mark@lange.demon.co.uk" - } - ], - "description": "PHP Class for working with complex numbers", - "homepage": "https://github.com/MarkBaker/PHPComplex", - "keywords": [ - "complex", - "mathematics" - ], - "support": { - "issues": "https://github.com/MarkBaker/PHPComplex/issues", - "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2" - }, - "time": "2022-12-06T16:21:08+00:00" - }, - { - "name": "markbaker/matrix", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/MarkBaker/PHPMatrix.git", - "reference": "728434227fe21be27ff6d86621a1b13107a2562c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c", - "reference": "728434227fe21be27ff6d86621a1b13107a2562c", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "dev-master", - "phpcompatibility/php-compatibility": "^9.3", - "phpdocumentor/phpdocumentor": "2.*", - "phploc/phploc": "^4.0", - "phpmd/phpmd": "2.*", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", - "sebastian/phpcpd": "^4.0", - "squizlabs/php_codesniffer": "^3.7" - }, - "type": "library", - "autoload": { - "psr-4": { - "Matrix\\": "classes/src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mark Baker", - "email": "mark@demon-angel.eu" - } - ], - "description": "PHP Class for working with matrices", - "homepage": "https://github.com/MarkBaker/PHPMatrix", - "keywords": [ - "mathematics", - "matrix", - "vector" - ], - "support": { - "issues": "https://github.com/MarkBaker/PHPMatrix/issues", - "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1" - }, - "time": "2022-12-02T22:17:43+00:00" - }, - { - "name": "myclabs/php-enum", - "version": "1.8.4", - "source": { - "type": "git", - "url": "https://github.com/myclabs/php-enum.git", - "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/php-enum/zipball/a867478eae49c9f59ece437ae7f9506bfaa27483", - "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "1.*", - "vimeo/psalm": "^4.6.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "MyCLabs\\Enum\\": "src/" - }, - "classmap": [ - "stubs/Stringable.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP Enum contributors", - "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" - } - ], - "description": "PHP Enum implementation", - "homepage": "http://github.com/myclabs/php-enum", - "keywords": [ - "enum" - ], - "support": { - "issues": "https://github.com/myclabs/php-enum/issues", - "source": "https://github.com/myclabs/php-enum/tree/1.8.4" - }, - "funding": [ - { - "url": "https://github.com/mnapoli", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", - "type": "tidelift" - } - ], - "time": "2022-08-04T09:53:51+00:00" - }, - { - "name": "phpoffice/phpspreadsheet", - "version": "1.27.0", - "source": { - "type": "git", - "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "eeb8582f9cabf5a7f4ef78015691163233a1834f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/eeb8582f9cabf5a7f4ef78015691163233a1834f", - "reference": "eeb8582f9cabf5a7f4ef78015691163233a1834f", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-dom": "*", - "ext-fileinfo": "*", - "ext-gd": "*", - "ext-iconv": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-simplexml": "*", - "ext-xml": "*", - "ext-xmlreader": "*", - "ext-xmlwriter": "*", - "ext-zip": "*", - "ext-zlib": "*", - "ezyang/htmlpurifier": "^4.15", - "maennchen/zipstream-php": "^2.1", - "markbaker/complex": "^3.0", - "markbaker/matrix": "^3.0", - "php": "^7.4 || ^8.0", - "psr/http-client": "^1.0", - "psr/http-factory": "^1.0", - "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "dev-master", - "dompdf/dompdf": "^1.0 || ^2.0", - "friendsofphp/php-cs-fixer": "^3.2", - "mitoteam/jpgraph": "^10.2.4", - "mpdf/mpdf": "^8.1.1", - "phpcompatibility/php-compatibility": "^9.3", - "phpstan/phpstan": "^1.1", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^8.5 || ^9.0", - "squizlabs/php_codesniffer": "^3.7", - "tecnickcom/tcpdf": "^6.5" - }, - "suggest": { - "dompdf/dompdf": "Option for rendering PDF with PDF Writer", - "ext-intl": "PHP Internationalization Functions", - "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", - "mpdf/mpdf": "Option for rendering PDF with PDF Writer", - "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" - }, - "type": "library", - "autoload": { - "psr-4": { - "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Maarten Balliauw", - "homepage": "https://blog.maartenballiauw.be" - }, - { - "name": "Mark Baker", - "homepage": "https://markbakeruk.net" - }, - { - "name": "Franck Lefevre", - "homepage": "https://rootslabs.net" - }, - { - "name": "Erik Tilt" - }, - { - "name": "Adrien Crivelli" - } - ], - "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", - "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", - "keywords": [ - "OpenXML", - "excel", - "gnumeric", - "ods", - "php", - "spreadsheet", - "xls", - "xlsx" - ], - "support": { - "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.27.0" - }, - "time": "2023-01-24T20:07:45+00:00" - }, - { - "name": "psr/http-client", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.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": "http://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/tree/master" - }, - "time": "2020-06-29T06:28:15+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.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": "http://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/master" - }, - "time": "2019-04-30T12:38:16+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.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": "http://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/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "psr/simple-cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" - }, - "time": "2021-10-29T13:26:27+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v6.2.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "e59e8a4006afd7f5654786a83b4fcb8da98f4593" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e59e8a4006afd7f5654786a83b4fcb8da98f4593", - "reference": "e59e8a4006afd7f5654786a83b4fcb8da98f4593", - "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.2.5" - }, - "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-01-20T17:45:48+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "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.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "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.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/serializer", - "version": "v6.2.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/serializer.git", - "reference": "dec3263bd7399f85cc54ea51a019e60b085759f0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/dec3263bd7399f85cc54ea51a019e60b085759f0", - "reference": "dec3263bd7399f85cc54ea51a019e60b085759f0", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "doctrine/annotations": "<1.12", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0|>=1.7.0", - "symfony/dependency-injection": "<5.4", - "symfony/property-access": "<5.4", - "symfony/property-info": "<5.4", - "symfony/uid": "<5.4", - "symfony/yaml": "<5.4" - }, - "require-dev": { - "doctrine/annotations": "^1.12|^2", - "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", - "symfony/cache": "^5.4|^6.0", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/error-handler": "^5.4|^6.0", - "symfony/filesystem": "^5.4|^6.0", - "symfony/form": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0", - "symfony/var-exporter": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" - }, - "suggest": { - "psr/cache-implementation": "For using the metadata cache.", - "symfony/config": "For using the XML mapping loader.", - "symfony/mime": "For using a MIME type guesser within the DataUriNormalizer.", - "symfony/property-access": "For using the ObjectNormalizer.", - "symfony/property-info": "To deserialize relations.", - "symfony/var-exporter": "For using the metadata compiler.", - "symfony/yaml": "For using the default YAML mapping loader." - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Serializer\\": "" - }, - "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": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/serializer/tree/v6.2.5" - }, - "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-01-20T17:45:48+00:00" - } - ], - "packages-dev": [ - { - "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": "masterminds/html5", - "version": "2.7.6", - "source": { - "type": "git", - "url": "https://github.com/Masterminds/html5-php.git", - "reference": "897eb517a343a2281f11bc5556d6548db7d93947" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/897eb517a343a2281f11bc5556d6548db7d93947", - "reference": "897eb517a343a2281f11bc5556d6548db7d93947", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-dom": "*", - "ext-libxml": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Masterminds\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matt Butcher", - "email": "technosophos@gmail.com" - }, - { - "name": "Matt Farina", - "email": "matt@mattfarina.com" - }, - { - "name": "Asmir Mustafic", - "email": "goetas@gmail.com" - } - ], - "description": "An HTML5 parser and serializer.", - "homepage": "http://masterminds.github.io/html5-php", - "keywords": [ - "HTML5", - "dom", - "html", - "parser", - "querypath", - "serializer", - "xml" - ], - "support": { - "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.7.6" - }, - "time": "2022-08-18T16:18:26+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "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.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.3", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/570e980a201d8ed0236b0a62ddf2c9cbb2034039", - "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039", - "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.15.3" - }, - "time": "2023-01-16T22:05:37+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "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.3" - }, - "time": "2021-07-20T11:28:43+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.24", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2cf940ebc6355a9d430462811b5aaa308b174bed", - "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "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": "*", - "ext-xdebug": "*" - }, - "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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.24" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-01-26T08:26:55+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.5.28", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "954ca3113a03bf780d22f07bf055d883ee04b65e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/954ca3113a03bf780d22f07bf055d883ee04b65e", - "reference": "954ca3113a03bf780d22f07bf055d883ee04b65e", - "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.13", - "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": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.5-dev" - } - }, - "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.28" - }, - "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": "2023-01-14T12:32:24+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "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.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+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.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "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.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "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.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "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.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-03T09:37:03+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "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.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "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.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "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.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+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.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "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": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+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.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "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.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-12T14:47: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": "symfony/browser-kit", - "version": "v6.2.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/browser-kit.git", - "reference": "ea591a69d714216d29cb67b519b509bd32b735a2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/ea591a69d714216d29cb67b519b509bd32b735a2", - "reference": "ea591a69d714216d29cb67b519b509bd32b735a2", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/dom-crawler": "^5.4|^6.0" - }, - "require-dev": { - "symfony/css-selector": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0" - }, - "suggest": { - "symfony/process": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\BrowserKit\\": "" - }, - "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": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/browser-kit/tree/v6.2.5" - }, - "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-01-01T08:38:09+00:00" - }, - { - "name": "symfony/css-selector", - "version": "v6.2.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "bf1b9d4ad8b1cf0dbde8b08e0135a2f6259b9ba1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/bf1b9d4ad8b1cf0dbde8b08e0135a2f6259b9ba1", - "reference": "bf1b9d4ad8b1cf0dbde8b08e0135a2f6259b9ba1", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Converts CSS selectors to XPath expressions", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.2.5" - }, - "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-01-01T08:38:09+00:00" - }, - { - "name": "symfony/dom-crawler", - "version": "v6.2.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/dom-crawler.git", - "reference": "19aa4962a0687e96941f0bdb27b794c5b73e2394" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/19aa4962a0687e96941f0bdb27b794c5b73e2394", - "reference": "19aa4962a0687e96941f0bdb27b794c5b73e2394", - "shasum": "" - }, - "require": { - "masterminds/html5": "^2.6", - "php": ">=8.1", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "symfony/css-selector": "^5.4|^6.0" - }, - "suggest": { - "symfony/css-selector": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\DomCrawler\\": "" - }, - "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 DOM navigation for HTML and XML documents", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.2.5" - }, - "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-01-20T17:45:48+00:00" - }, - { - "name": "symfony/phpunit-bridge", - "version": "v6.2.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "d759e5372de414bef53a688c7aa7e240e4fd8aa2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/d759e5372de414bef53a688c7aa7e240e4fd8aa2", - "reference": "d759e5372de414bef53a688c7aa7e240e4fd8aa2", - "shasum": "" - }, - "require": { - "php": ">=7.1.3" - }, - "conflict": { - "phpunit/phpunit": "<7.5|9.1.2" - }, - "require-dev": { - "symfony/deprecation-contracts": "^2.1|^3.0", - "symfony/error-handler": "^5.4|^6.0" - }, - "suggest": { - "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" - }, - "bin": [ - "bin/simple-phpunit" - ], - "type": "symfony-bridge", - "extra": { - "thanks": { - "name": "phpunit/phpunit", - "url": "https://github.com/sebastianbergmann/phpunit" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Bridge\\PhpUnit\\": "" - }, - "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 utilities for PHPUnit, especially user deprecation notices management", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.2.5" - }, - "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-01-01T08:38:09+00:00" - }, - { - "name": "symfony/test-pack", - "version": "1.0.10", - "source": { - "type": "git", - "url": "https://github.com/symfony/test-pack.git", - "reference": "03ab012f4aab784690d21417f7cdd7b432fd4e73" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/test-pack/zipball/03ab012f4aab784690d21417f7cdd7b432fd4e73", - "reference": "03ab012f4aab784690d21417f7cdd7b432fd4e73", - "shasum": "" - }, - "require": { - "phpunit/phpunit": "*", - "symfony/browser-kit": "*", - "symfony/css-selector": "*", - "symfony/phpunit-bridge": "*" - }, - "require-dev": { - "phpunit/phpunit": "*", - "symfony/browser-kit": "*", - "symfony/css-selector": "*", - "symfony/phpunit-bridge": "*" - }, - "type": "symfony-pack", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A pack for functional and end-to-end testing within a Symfony app", - "support": { - "issues": "https://github.com/symfony/test-pack/issues", - "source": "https://github.com/symfony/test-pack/tree/1.0.10" - }, - "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": "2022-04-15T12:25:45+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=8.1" - }, - "platform-dev": [], - "plugin-api-version": "2.3.0" -} diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..8c4e835 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,10 @@ + + + + + + + src/ + tests/ + diff --git a/phpstan.neon b/phpstan.neon index dca642a..0914f0f 100755 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,7 @@ parameters: paths: - %currentWorkingDirectory%/src - checkMissingIterableValueType: false \ No newline at end of file + - %currentWorkingDirectory%/tests/ + +includes: + - vendor/assoconnect/php-quality-config/phpstan.extension.neon \ No newline at end of file diff --git a/src/ExcelEncoder.php b/src/ExcelEncoder.php index ee6b335..9d0192e 100755 --- a/src/ExcelEncoder.php +++ b/src/ExcelEncoder.php @@ -9,7 +9,7 @@ * with this source code in the file LICENSE. */ -namespace Ang3\Component\Serializer\Encoder; +namespace AssoConnect\Serializer\Encoder; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; @@ -47,14 +47,18 @@ class ExcelEncoder implements EncoderInterface, DecoderInterface public const COLUMNS_AUTOSIZE_KEY = 'columns_autosize'; public const COLUMNS_MAXSIZE_KEY = 'columns_maxsize'; + /** - * @static + * @var string[] */ private static array $formats = [ self::XLS, self::XLSX, ]; + /** + * @var array + */ private array $defaultContext = [ self::AS_COLLECTION_KEY => true, self::FLATTENED_HEADERS_SEPARATOR_KEY => '.', @@ -66,6 +70,9 @@ class ExcelEncoder implements EncoderInterface, DecoderInterface private Filesystem $filesystem; + /** + * @param mixed[] $defaultContext + */ public function __construct(array $defaultContext = []) { $this->defaultContext = array_merge($this->defaultContext, $defaultContext); @@ -97,26 +104,23 @@ public function encode($data, $format, array $context = []): string $context = $this->normalizeContext($context); $spreadsheet = new Spreadsheet(); - switch ($format) { - // Excel 2007 - case self::XLSX: - $writer = new Writers\Xlsx($spreadsheet); - break; - - // Excel 2003 - case self::XLS: - $writer = new Writers\Xls($spreadsheet); - break; - - default: - throw new InvalidArgumentException(sprintf('The format "%s" is not supported', $format)); - } + $writer = match ($format) { + self::XLSX => new Writers\Xlsx($spreadsheet), + self::XLS => new Writers\Xls($spreadsheet), + default => throw new InvalidArgumentException(sprintf('The format "%s" is not supported', $format)), + }; $sheetIndex = 0; foreach ($data as $sheetName => $sheetData) { if (!is_iterable($sheetData)) { - throw new NotEncodableValueException(sprintf('Expected data of sheet #%d of type "iterable", "%s" given', $sheetName, \gettype($sheetData))); + throw new NotEncodableValueException( + sprintf( + 'Expected data of sheet #%d of type "iterable", "%s" given', + $sheetName, + \gettype($sheetData) + ) + ); } if ($sheetIndex > 0) { @@ -126,11 +130,18 @@ public function encode($data, $format, array $context = []): string $spreadsheet->setActiveSheetIndex($sheetIndex); $worksheet = $spreadsheet->getActiveSheet(); $worksheet->setTitle($sheetName); - $sheetData = (array) $sheetData; + $sheetData = (array)$sheetData; foreach ($sheetData as $rowIndex => $cells) { if (!is_iterable($cells)) { - throw new NotEncodableValueException(sprintf('Expected cells of type "iterable" for data sheet #%d at row #%d, "%s" given', $sheetIndex, $rowIndex, \gettype($cells))); + throw new NotEncodableValueException( + sprintf( + 'Expected cells of type "iterable" for data sheet #%d at row #%d, "%s" given', + $sheetIndex, + $rowIndex, + \gettype($cells) + ) + ); } $flattened = []; @@ -148,41 +159,36 @@ public function encode($data, $format, array $context = []): string array_unshift($sheetData, $headers); $worksheet->fromArray($sheetData, null, 'A1', true); - $headerLineStyle = $worksheet->getStyle('A1:'.$worksheet->getHighestDataColumn().'1'); + $headerLineStyle = $worksheet->getStyle('A1:' . $worksheet->getHighestDataColumn() . '1'); if ($context[self::HEADERS_HORIZONTAL_ALIGNMENT_KEY]) { - switch ($context[self::HEADERS_HORIZONTAL_ALIGNMENT_KEY]) { - case 'left': - $alignment = Alignment::HORIZONTAL_LEFT; - break; - case 'center': - $alignment = Alignment::HORIZONTAL_CENTER; - break; - case 'right': - $alignment = Alignment::HORIZONTAL_RIGHT; - break; - default: - throw new InvalidArgumentException(sprintf('The value of context key "%s" is not valid (possible values: "left", "center" or "right")', self::HEADERS_HORIZONTAL_ALIGNMENT_KEY)); - } + $alignment = match ($context[self::HEADERS_HORIZONTAL_ALIGNMENT_KEY]) { + 'left' => Alignment::HORIZONTAL_LEFT, + 'center' => Alignment::HORIZONTAL_CENTER, + 'right' => Alignment::HORIZONTAL_RIGHT, + default => throw new InvalidArgumentException( + sprintf( + 'The value of context key "%s" is not valid (possible values: "left", "center" or "right")', + self::HEADERS_HORIZONTAL_ALIGNMENT_KEY + ) + ), + }; $headerLineStyle ->getAlignment() - ->setHorizontal($alignment) - ; + ->setHorizontal($alignment); } if (true === $context[self::HEADERS_IN_BOLD_KEY]) { $headerLineStyle ->getFont() - ->setBold(true) - ; + ->setBold(true); } for ($i = 1; $i <= Coordinate::columnIndexFromString($worksheet->getHighestDataColumn()); ++$i) { $worksheet ->getColumnDimensionByColumn($i) - ->setAutoSize($context[self::COLUMNS_AUTOSIZE_KEY]) - ; + ->setAutoSize($context[self::COLUMNS_AUTOSIZE_KEY]); } $worksheet->calculateColumnWidths(); @@ -202,7 +208,7 @@ public function encode($data, $format, array $context = []): string try { $tmpFile = $this->filesystem->tempnam(sys_get_temp_dir(), $format); $writer->save($tmpFile); - $content = (string) file_get_contents($tmpFile); + $content = (string)file_get_contents($tmpFile); $this->filesystem->remove($tmpFile); } catch (\Exception $e) { throw new RuntimeException(sprintf('Excel encoding failed - %s', $e->getMessage()), 0, $e); @@ -227,30 +233,21 @@ public function supportsDecoding($format): bool * @throws RuntimeException When data reading failed * @throws PhpSpreadsheetException On data failure */ - public function decode($data, $format, array $context = []) + public function decode($data, $format, array $context = []): mixed { if (!\is_scalar($data)) { throw new NotEncodableValueException(sprintf('Expected data of type scalar, %s given', \gettype($data))); } $context = $this->normalizeContext($context); - $tmpFile = (string) tempnam(sys_get_temp_dir(), $format); + $tmpFile = (string)tempnam(sys_get_temp_dir(), $format); $this->filesystem->dumpFile($tmpFile, $data); - switch ($format) { - // Excel 2007 - case self::XLSX: - $reader = new Readers\Xlsx(); - break; - - // Excel 2003 - case self::XLS: - $reader = new Readers\Xls(); - break; - - default: - throw new InvalidArgumentException(sprintf('The format "%s" is not supported', $format)); - } + $reader = match ($format) { + self::XLSX => new Readers\Xlsx(), + self::XLS => new Readers\Xls(), + default => throw new InvalidArgumentException(sprintf('The format "%s" is not supported', $format)), + }; try { $spreadsheet = $reader->load($tmpFile); @@ -280,7 +277,7 @@ public function decode($data, $format, array $context = []) $headers = null; foreach ($sheetData as $rowIndex => $cells) { - $rowIndex = (int) $rowIndex; + $rowIndex = (int)$rowIndex; if (null === $headers) { $headers = []; @@ -299,7 +296,7 @@ public function decode($data, $format, array $context = []) foreach ($cells as $key => $value) { if (\array_key_exists($key, $headers)) { - $labelledRows[$rowIndex - 1][(string) $headers[$key]] = $value; + $labelledRows[$rowIndex - 1][(string)$headers[$key]] = $value; } else { $labelledRows[$rowIndex - 1][''][$key] = $value; } @@ -317,9 +314,9 @@ public function decode($data, $format, array $context = []) } /** + * @throws NotNormalizableValueException when a value is not valid * @internal * - * @throws NotNormalizableValueException when a value is not valid */ private function flatten(iterable $data, array &$result, string $keySeparator, string $parentKey = ''): void { @@ -329,15 +326,17 @@ private function flatten(iterable $data, array &$result, string $keySeparator, s } if (is_iterable($value)) { - $this->flatten($value, $result, $keySeparator, $parentKey.$key.$keySeparator); + $this->flatten($value, $result, $keySeparator, $parentKey . $key . $keySeparator); continue; } - $newKey = $parentKey.$key; + $newKey = $parentKey . $key; if (!\is_scalar($value)) { - throw new NotNormalizableValueException(sprintf('Expected key "%s" of type object, array or scalar, %s given', $newKey, \gettype($value))); + throw new NotNormalizableValueException( + sprintf('Expected key "%s" of type object, array or scalar, %s given', $newKey, \gettype($value)) + ); } $result[sprintf('="%s"', $newKey)] = false === $value ? 0 : (true === $value ? 1 : $value); @@ -345,22 +344,33 @@ private function flatten(iterable $data, array &$result, string $keySeparator, s } /** + * @param mixed[] $context + * @return mixed[] * @internal + * */ private function normalizeContext(array $context = []): array { return [ - self::AS_COLLECTION_KEY => (bool) $this->getContextValue($context, self::AS_COLLECTION_KEY), - self::FLATTENED_HEADERS_SEPARATOR_KEY => (string) $this->getContextValue($context, self::FLATTENED_HEADERS_SEPARATOR_KEY), - self::HEADERS_IN_BOLD_KEY => (bool) $this->getContextValue($context, self::HEADERS_IN_BOLD_KEY), - self::HEADERS_HORIZONTAL_ALIGNMENT_KEY => (string) $this->getContextValue($context, self::HEADERS_HORIZONTAL_ALIGNMENT_KEY), - self::COLUMNS_AUTOSIZE_KEY => (bool) $this->getContextValue($context, self::COLUMNS_AUTOSIZE_KEY), - self::COLUMNS_MAXSIZE_KEY => (int) $this->getContextValue($context, self::COLUMNS_MAXSIZE_KEY), + self::AS_COLLECTION_KEY => (bool)$this->getContextValue($context, self::AS_COLLECTION_KEY), + self::FLATTENED_HEADERS_SEPARATOR_KEY => (string)$this->getContextValue( + $context, + self::FLATTENED_HEADERS_SEPARATOR_KEY + ), + self::HEADERS_IN_BOLD_KEY => (bool)$this->getContextValue($context, self::HEADERS_IN_BOLD_KEY), + self::HEADERS_HORIZONTAL_ALIGNMENT_KEY => (string)$this->getContextValue( + $context, + self::HEADERS_HORIZONTAL_ALIGNMENT_KEY + ), + self::COLUMNS_AUTOSIZE_KEY => (bool)$this->getContextValue($context, self::COLUMNS_AUTOSIZE_KEY), + self::COLUMNS_MAXSIZE_KEY => (int)$this->getContextValue($context, self::COLUMNS_MAXSIZE_KEY), ]; } /** + * @param mixed[] $context * @internal + * */ private function getContextValue(array $context, int|string $key): bool|int|float|string|null { diff --git a/tests.phpstan.neon b/tests.phpstan.neon deleted file mode 100755 index fe7c388..0000000 --- a/tests.phpstan.neon +++ /dev/null @@ -1,6 +0,0 @@ -parameters: - autoload_files: - - vendor/bin/.phpunit/phpunit-8.3-0/vendor/autoload.php - paths: - - %currentWorkingDirectory%/tests - checkMissingIterableValueType: false \ No newline at end of file diff --git a/tests/ExcelEncoderTest.php b/tests/ExcelEncoderTest.php index 1336b2c..e621dd5 100755 --- a/tests/ExcelEncoderTest.php +++ b/tests/ExcelEncoderTest.php @@ -3,15 +3,15 @@ declare(strict_types=1); /* - * This file is part of package ang3/php-excel-encoder + * This file is part of package assoconnect/php-excel-encoder * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ -namespace Ang3\Component\Serializer\Encoder\Tests; +namespace AssoConnect\Serializer\Encoder\Tests; -use Ang3\Component\Serializer\Encoder\ExcelEncoder; +use AssoConnect\Serializer\Encoder\ExcelEncoder; use PHPUnit\Framework\TestCase; /** @@ -19,7 +19,7 @@ * * @internal * - * @covers \Ang3\Component\Serializer\Encoder\ExcelEncoder + * @covers \AssoConnect\Serializer\Encoder\ExcelEncoder */ final class ExcelEncoderTest extends TestCase { @@ -53,86 +53,94 @@ public function testEncode(string $format): void public static function dataDecodingProvider(): array { return [ - [__DIR__.'/Resources/encoded.xls', ExcelEncoder::XLS, [ - 'Sheet_0' => [ - [ - 'bool' => 0.0, - 'int' => 1, - 'float' => 1.618, - 'string' => 'Hello', - 'object.date' => '2000-01-01 13:37:00.000000', - 'object.timezone_type' => 3, - 'object.timezone' => 'Europe/Berlin', - 'array.bool' => 1, - 'array.int' => 3, - 'array.float' => 3.14, - 'array.string' => 'World', - 'array.object.date' => '2000-01-01 13:37:00.000000', - 'array.object.timezone_type' => 3, - 'array.object.timezone' => 'Europe/Berlin', - 'array.array.0' => 'again', + [ + __DIR__ . '/Resources/encoded.xls', + ExcelEncoder::XLS, + [ + 'Sheet_0' => [ + [ + 'bool' => 0.0, + 'int' => 1, + 'float' => 1.618, + 'string' => 'Hello', + 'object.date' => '2000-01-01 13:37:00.000000', + 'object.timezone_type' => 3, + 'object.timezone' => 'Europe/Berlin', + 'array.bool' => 1, + 'array.int' => 3, + 'array.float' => 3.14, + 'array.string' => 'World', + 'array.object.date' => '2000-01-01 13:37:00.000000', + 'array.object.timezone_type' => 3, + 'array.object.timezone' => 'Europe/Berlin', + 'array.array.0' => 'again', + ], ], - ], - 'Feuil1' => [ - [ - 'bool' => 0.0, - 'int' => 1, - 'float' => 1.618, - 'string' => 'Hello', - 'object.date' => '2000-01-01 13:37:00.000000', - 'object.timezone_type' => 3, - 'object.timezone' => 'Europe/Berlin', - 'array.bool' => 1, - 'array.int' => 3, - 'array.float' => 3.14, - 'array.string' => 'World', - 'array.object.date' => '2000-01-01 13:37:00.000000', - 'array.object.timezone_type' => 3, - 'array.object.timezone' => 'Europe/Berlin', - 'array.array.0' => 'again', + 'Feuil1' => [ + [ + 'bool' => 0.0, + 'int' => 1, + 'float' => 1.618, + 'string' => 'Hello', + 'object.date' => '2000-01-01 13:37:00.000000', + 'object.timezone_type' => 3, + 'object.timezone' => 'Europe/Berlin', + 'array.bool' => 1, + 'array.int' => 3, + 'array.float' => 3.14, + 'array.string' => 'World', + 'array.object.date' => '2000-01-01 13:37:00.000000', + 'array.object.timezone_type' => 3, + 'array.object.timezone' => 'Europe/Berlin', + 'array.array.0' => 'again', + ], ], ], - ]], - [__DIR__.'/Resources/encoded.xlsx', ExcelEncoder::XLSX, [ - 'Sheet_0' => [ - [ - 'bool' => 0, - 'int' => 1, - 'float' => 1.618, - 'string' => 'Hello', - 'object.date' => '2000-01-01 13:37:00.000000', - 'object.timezone_type' => 3, - 'object.timezone' => 'Europe/Berlin', - 'array.bool' => 1, - 'array.int' => 3, - 'array.float' => 3.14, - 'array.string' => 'World', - 'array.object.date' => '2000-01-01 13:37:00.000000', - 'array.object.timezone_type' => 3, - 'array.object.timezone' => 'Europe/Berlin', - 'array.array.0' => 'again', + ], + [ + __DIR__ . '/Resources/encoded.xlsx', + ExcelEncoder::XLSX, + [ + 'Sheet_0' => [ + [ + 'bool' => 0, + 'int' => 1, + 'float' => 1.618, + 'string' => 'Hello', + 'object.date' => '2000-01-01 13:37:00.000000', + 'object.timezone_type' => 3, + 'object.timezone' => 'Europe/Berlin', + 'array.bool' => 1, + 'array.int' => 3, + 'array.float' => 3.14, + 'array.string' => 'World', + 'array.object.date' => '2000-01-01 13:37:00.000000', + 'array.object.timezone_type' => 3, + 'array.object.timezone' => 'Europe/Berlin', + 'array.array.0' => 'again', + ], ], - ], - 'Feuil1' => [ - [ - 'bool' => 0, - 'int' => 1, - 'float' => 1.618, - 'string' => 'Hello', - 'object.date' => '2000-01-01 13:37:00.000000', - 'object.timezone_type' => 3, - 'object.timezone' => 'Europe/Berlin', - 'array.bool' => 1, - 'array.int' => 3, - 'array.float' => 3.14, - 'array.string' => 'World', - 'array.object.date' => '2000-01-01 13:37:00.000000', - 'array.object.timezone_type' => 3, - 'array.object.timezone' => 'Europe/Berlin', - 'array.array.0' => 'again', + 'Feuil1' => [ + [ + 'bool' => 0, + 'int' => 1, + 'float' => 1.618, + 'string' => 'Hello', + 'object.date' => '2000-01-01 13:37:00.000000', + 'object.timezone_type' => 3, + 'object.timezone' => 'Europe/Berlin', + 'array.bool' => 1, + 'array.int' => 3, + 'array.float' => 3.14, + 'array.string' => 'World', + 'array.object.date' => '2000-01-01 13:37:00.000000', + 'array.object.timezone_type' => 3, + 'array.object.timezone' => 'Europe/Berlin', + 'array.array.0' => 'again', + ], ], ], - ]], + ], ]; } @@ -141,7 +149,7 @@ public static function dataDecodingProvider(): array */ public function testDecode(string $file, string $format, array $result): void { - static::assertSame($result, $this->encoder->decode((string) file_get_contents($file), $format)); + static::assertSame($result, $this->encoder->decode((string)file_get_contents($file), $format)); } /** From db7114e46d159196ff9e3cdaec7f7543733f2cdd Mon Sep 17 00:00:00 2001 From: Florian Guimier Date: Fri, 20 Dec 2024 15:10:08 +0100 Subject: [PATCH 2/3] Revert "Revert "Fix (#5)"" This reverts commit e7e5aa97db5fb606b391e0ff7a6a2b223d52cf92. --- .github/workflows/build.yml | 6 +- README.md | 7 +- composer.json | 4 +- phpstan-baseline.neon | 46 ++++ phpstan.neon => phpstan.neon.dist | 1 + src/ExcelEncoder.php | 349 +++++++++++++++++------------- tests/ExcelEncoderTest.php | 203 +++++++---------- 7 files changed, 333 insertions(+), 283 deletions(-) create mode 100644 phpstan-baseline.neon rename phpstan.neon => phpstan.neon.dist (86%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 83185a2..c7e79e9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Build on: push: - branches: [ master ] + branches: [ main ] pull_request: types: [opened, synchronize, reopened] @@ -49,8 +49,8 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: args: > - -Dsonar.projectName=[your-repo] - -Dsonar.projectKey=assoconnect_[your-repo] + -Dsonar.projectName=php-excel-encoder + -Dsonar.projectKey=assoconnect_php-excel-encoder -Dsonar.organization=assoconnect -Dsonar.sources=src -Dsonar.tests=tests diff --git a/README.md b/README.md index 9e59ce5..f24a5d6 100755 --- a/README.md +++ b/README.md @@ -1,11 +1,8 @@ PHP Excel encoder ================= -[![Code Quality](https://github.com/Ang3/php-excel-encoder/actions/workflows/php_lint.yml/badge.svg)](https://github.com/Ang3/php-excel-encoder/actions/workflows/php_lint.yml) -[![PHPUnit Tests](https://github.com/Ang3/php-excel-encoder/actions/workflows/phpunit.yml/badge.svg)](https://github.com/Ang3/php-excel-encoder/actions/workflows/phpunit.yml) -[![Symfony Integration](https://github.com/Ang3/php-excel-encoder/actions/workflows/symfony.yml/badge.svg)](https://github.com/Ang3/php-excel-encoder/actions/workflows/symfony.yml) -[![Latest Stable Version](https://poser.pugx.org/ang3/php-excel-encoder/v/stable)](https://packagist.org/packages/ang3/php-excel-encoder) -[![Total Downloads](https://poser.pugx.org/ang3/php-excel-encoder/downloads)](https://packagist.org/packages/ang3/php-excel-encoder) +[![Code Quality](https://github.com/assoconnect/php-excel-encoder/actions/workflows/build.yml/badge.svg)](https://github.com/assoconnect/php-excel-encoder/actions/workflows/build.yml) +[![Latest Stable Version](https://poser.pugx.org/assoconnect/php-excel-encoder/v/stable)](https://packagist.org/packages/assoconnect/php-excel-encoder) Encode and decode xls/xlsx files and more thanks to the component [phpoffice/phpspreadsheet](https://phpspreadsheet.readthedocs.io/en/latest/). diff --git a/composer.json b/composer.json index 25964c7..1f6d90c 100755 --- a/composer.json +++ b/composer.json @@ -27,8 +27,8 @@ "require": { "php": "^8.2", "phpoffice/phpspreadsheet": "^1.16|^2.0", - "symfony/serializer": "^6.0|^7.0", - "symfony/filesystem": "^6.0|^7.0" + "symfony/serializer": "^6.0", + "symfony/filesystem": "^6.0" }, "require-dev": { "symfony/test-pack": "^1.0", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..2708bf8 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,46 @@ +parameters: + ignoreErrors: + - + message: "#^Cannot assign float\\|int\\|string to \\$result\\[sprintf\\('\\=\"%%s\"', \\$newKey\\)\\] \\- floats are not allowed\\.$#" + count: 1 + path: src/ExcelEncoder.php + + - + message: "#^Comparison float \\> mixed contains non\\-comparable type, only int\\|float\\|string\\|DateTimeInterface or comparable tuple is allowed\\.$#" + count: 1 + path: src/ExcelEncoder.php + + - + message: "#^Method AssoConnect\\\\Serializer\\\\Encoder\\\\ExcelEncoder\\:\\:getContextValue\\(\\) cannot have bool\\|float\\|int\\|string\\|null as its return type \\- floats are not allowed\\.$#" + count: 1 + path: src/ExcelEncoder.php + + - + message: "#^Only booleans are allowed in an if condition, mixed given\\.$#" + count: 1 + path: src/ExcelEncoder.php + + - + message: "#^Overwriting variable \\$data while changing its type from string to array\\{\\}$#" + count: 1 + path: src/ExcelEncoder.php + + - + message: "#^Overwriting variable \\$value while changing its type from object to array\\$#" + count: 1 + path: src/ExcelEncoder.php + + - + message: "#^Using \\(array\\) is discouraged, please avoid using that\\.$#" + count: 1 + path: src/ExcelEncoder.php + + - + message: "#^Method AssoConnect\\\\Serializer\\\\Encoder\\\\Tests\\\\ExcelEncoderTest\\:\\:getInitialData\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: tests/ExcelEncoderTest.php + + - + message: "#^Method AssoConnect\\\\Serializer\\\\Encoder\\\\Tests\\\\ExcelEncoderTest\\:\\:provideDataDecoding\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: tests/ExcelEncoderTest.php diff --git a/phpstan.neon b/phpstan.neon.dist similarity index 86% rename from phpstan.neon rename to phpstan.neon.dist index 0914f0f..7415e14 100755 --- a/phpstan.neon +++ b/phpstan.neon.dist @@ -4,4 +4,5 @@ parameters: - %currentWorkingDirectory%/tests/ includes: + - phpstan-baseline.neon - vendor/assoconnect/php-quality-config/phpstan.extension.neon \ No newline at end of file diff --git a/src/ExcelEncoder.php b/src/ExcelEncoder.php index 9d0192e..2ce1ea2 100755 --- a/src/ExcelEncoder.php +++ b/src/ExcelEncoder.php @@ -16,7 +16,9 @@ use PhpOffice\PhpSpreadsheet\Reader as Readers; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\Alignment; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use PhpOffice\PhpSpreadsheet\Writer as Writers; +use PhpOffice\PhpSpreadsheet\Writer\BaseWriter; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Serializer\Encoder\CsvEncoder; use Symfony\Component\Serializer\Encoder\DecoderInterface; @@ -59,14 +61,7 @@ class ExcelEncoder implements EncoderInterface, DecoderInterface /** * @var array */ - private array $defaultContext = [ - self::AS_COLLECTION_KEY => true, - self::FLATTENED_HEADERS_SEPARATOR_KEY => '.', - self::HEADERS_IN_BOLD_KEY => true, - self::HEADERS_HORIZONTAL_ALIGNMENT_KEY => 'center', - self::COLUMNS_AUTOSIZE_KEY => true, - self::COLUMNS_MAXSIZE_KEY => 50, - ]; + private array $defaultContext; private Filesystem $filesystem; @@ -75,14 +70,23 @@ class ExcelEncoder implements EncoderInterface, DecoderInterface */ public function __construct(array $defaultContext = []) { - $this->defaultContext = array_merge($this->defaultContext, $defaultContext); + $baseDefaultContext = [ + self::AS_COLLECTION_KEY => true, + self::FLATTENED_HEADERS_SEPARATOR_KEY => '.', + self::HEADERS_IN_BOLD_KEY => true, + self::HEADERS_HORIZONTAL_ALIGNMENT_KEY => 'center', + self::COLUMNS_AUTOSIZE_KEY => true, + self::COLUMNS_MAXSIZE_KEY => 50, + ]; + + $this->defaultContext = array_merge($baseDefaultContext, $defaultContext); $this->filesystem = new Filesystem(); } /** * {@inheritdoc}. */ - public function supportsEncoding($format): bool + public function supportsEncoding(string $format): bool { return \in_array($format, self::$formats, true); } @@ -90,12 +94,14 @@ public function supportsEncoding($format): bool /** * {@inheritdoc}. * + * @param mixed[] $context + * * @throws InvalidArgumentException When the format is not supported * @throws NotEncodableValueException When data are not valid * @throws RuntimeException When data writing failed * @throws PhpSpreadsheetException On data failure */ - public function encode($data, $format, array $context = []): string + public function encode(mixed $data, string $format, array $context = []): string { if (!is_iterable($data)) { throw new NotEncodableValueException(sprintf('Expected data of type iterable, %s given', \gettype($data))); @@ -111,138 +117,135 @@ public function encode($data, $format, array $context = []): string }; $sheetIndex = 0; - foreach ($data as $sheetName => $sheetData) { - if (!is_iterable($sheetData)) { - throw new NotEncodableValueException( - sprintf( - 'Expected data of sheet #%d of type "iterable", "%s" given', - $sheetName, - \gettype($sheetData) - ) - ); - } - - if ($sheetIndex > 0) { - $spreadsheet->createSheet($sheetIndex); - } + $this->processSheetData($sheetName, $sheetData, $spreadsheet, $context, $sheetIndex++); + } - $spreadsheet->setActiveSheetIndex($sheetIndex); - $worksheet = $spreadsheet->getActiveSheet(); - $worksheet->setTitle($sheetName); - $sheetData = (array)$sheetData; - - foreach ($sheetData as $rowIndex => $cells) { - if (!is_iterable($cells)) { - throw new NotEncodableValueException( - sprintf( - 'Expected cells of type "iterable" for data sheet #%d at row #%d, "%s" given', - $sheetIndex, - $rowIndex, - \gettype($cells) - ) - ); - } - - $flattened = []; - $this->flatten($cells, $flattened, $context[self::FLATTENED_HEADERS_SEPARATOR_KEY]); - $sheetData[$rowIndex] = $flattened; - } + return $this->writeToFile($writer, $format); + } - $headers = []; + /** + * @param string $sheetName + * @param iterable $sheetData + * @param Spreadsheet $spreadsheet + * @param mixed[] $context + * @param int $sheetIndex + * @return void + */ + private function processSheetData( + string $sheetName, + iterable $sheetData, + Spreadsheet $spreadsheet, + array $context, + int $sheetIndex + ): void { + if ($sheetIndex > 0) { + $spreadsheet->createSheet($sheetIndex); + } - foreach ($sheetData as $cells) { - $headers = array_keys($cells); + $spreadsheet->setActiveSheetIndex($sheetIndex); + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->setTitle($sheetName); + $sheetData = (array) $sheetData; - break; + foreach ($sheetData as $rowIndex => $cells) { + if (!is_iterable($cells)) { + throw new NotEncodableValueException( + sprintf( + 'Expected cells of type "iterable" for data sheet #%d at row #%d, "%s" given', + $sheetIndex, + $rowIndex, + \gettype($cells) + ) + ); } + $flattened = []; + $this->flatten($cells, $flattened, $context[self::FLATTENED_HEADERS_SEPARATOR_KEY]); + $sheetData[$rowIndex] = $flattened; + } - array_unshift($sheetData, $headers); - $worksheet->fromArray($sheetData, null, 'A1', true); - $headerLineStyle = $worksheet->getStyle('A1:' . $worksheet->getHighestDataColumn() . '1'); - - if ($context[self::HEADERS_HORIZONTAL_ALIGNMENT_KEY]) { - $alignment = match ($context[self::HEADERS_HORIZONTAL_ALIGNMENT_KEY]) { - 'left' => Alignment::HORIZONTAL_LEFT, - 'center' => Alignment::HORIZONTAL_CENTER, - 'right' => Alignment::HORIZONTAL_RIGHT, - default => throw new InvalidArgumentException( - sprintf( - 'The value of context key "%s" is not valid (possible values: "left", "center" or "right")', - self::HEADERS_HORIZONTAL_ALIGNMENT_KEY - ) - ), - }; - - $headerLineStyle - ->getAlignment() - ->setHorizontal($alignment); - } + $headers = []; + foreach ($sheetData as $cells) { + $headers = array_keys($cells); + break; + } + array_unshift($sheetData, $headers); + $worksheet->fromArray($sheetData, null, 'A1', true); - if (true === $context[self::HEADERS_IN_BOLD_KEY]) { - $headerLineStyle - ->getFont() - ->setBold(true); - } + $this->applyHeaderStyles($worksheet, $context); + } - for ($i = 1; $i <= Coordinate::columnIndexFromString($worksheet->getHighestDataColumn()); ++$i) { - $worksheet - ->getColumnDimensionByColumn($i) - ->setAutoSize($context[self::COLUMNS_AUTOSIZE_KEY]); - } + /** + * @param mixed[] $context + */ + private function applyHeaderStyles(Worksheet $worksheet, array $context): void + { + $headerLineStyle = $worksheet->getStyle('A1:' . $worksheet->getHighestDataColumn() . '1'); + if ($context[self::HEADERS_HORIZONTAL_ALIGNMENT_KEY]) { + $alignment = match ($context[self::HEADERS_HORIZONTAL_ALIGNMENT_KEY]) { + 'left' => Alignment::HORIZONTAL_LEFT, + 'center' => Alignment::HORIZONTAL_CENTER, + 'right' => Alignment::HORIZONTAL_RIGHT, + default => throw new InvalidArgumentException( + sprintf( + 'The value of context key "%s" is not valid (possible values: "left", "center" or "right")', + self::HEADERS_HORIZONTAL_ALIGNMENT_KEY + ) + ), + }; + $headerLineStyle->getAlignment()->setHorizontal($alignment); + } - $worksheet->calculateColumnWidths(); + if (true === $context[self::HEADERS_IN_BOLD_KEY]) { + $headerLineStyle->getFont()->setBold(true); + } - foreach ($worksheet->getColumnDimensions() as $columnDimension) { - $colWidth = $columnDimension->getWidth(); + for ($i = 1; $i <= Coordinate::columnIndexFromString($worksheet->getHighestDataColumn()); ++$i) { + $worksheet->getColumnDimensionByColumn($i)->setAutoSize($context[self::COLUMNS_AUTOSIZE_KEY]); + } + $worksheet->calculateColumnWidths(); - if ($colWidth > $context[self::COLUMNS_MAXSIZE_KEY]) { - $columnDimension->setAutoSize(false); - $columnDimension->setWidth($context[self::COLUMNS_MAXSIZE_KEY]); - } + foreach ($worksheet->getColumnDimensions() as $columnDimension) { + if ($columnDimension->getWidth() > $context[self::COLUMNS_MAXSIZE_KEY]) { + $columnDimension->setAutoSize(false); + $columnDimension->setWidth($context[self::COLUMNS_MAXSIZE_KEY]); } - - ++$sheetIndex; } + } + /** + * @param BaseWriter $writer + * @return string + */ + private function writeToFile(BaseWriter $writer, string $format): string + { try { $tmpFile = $this->filesystem->tempnam(sys_get_temp_dir(), $format); $writer->save($tmpFile); - $content = (string)file_get_contents($tmpFile); + $content = (string) file_get_contents($tmpFile); $this->filesystem->remove($tmpFile); } catch (\Exception $e) { throw new RuntimeException(sprintf('Excel encoding failed - %s', $e->getMessage()), 0, $e); } - return $content; } /** * {@inheritdoc}. */ - public function supportsDecoding($format): bool + public function supportsDecoding(string $format): bool { return \in_array($format, self::$formats, true); } /** - * {@inheritdoc}. - * * @throws NotEncodableValueException When data are not valid * @throws InvalidArgumentException When the format or data not supported * @throws RuntimeException When data reading failed * @throws PhpSpreadsheetException On data failure */ - public function decode($data, $format, array $context = []): mixed + private function loadSpreadsheet(string $tmpFile, string $format): Spreadsheet { - if (!\is_scalar($data)) { - throw new NotEncodableValueException(sprintf('Expected data of type scalar, %s given', \gettype($data))); - } - - $context = $this->normalizeContext($context); - $tmpFile = (string)tempnam(sys_get_temp_dir(), $format); - $this->filesystem->dumpFile($tmpFile, $data); - $reader = match ($format) { self::XLSX => new Readers\Xlsx(), self::XLS => new Readers\Xls(), @@ -250,70 +253,108 @@ public function decode($data, $format, array $context = []): mixed }; try { - $spreadsheet = $reader->load($tmpFile); - $this->filesystem->remove($tmpFile); + return $reader->load($tmpFile); } catch (\Exception $e) { throw new RuntimeException(sprintf('Excel decoding failed - %s', $e->getMessage()), 0, $e); + } finally { + $this->filesystem->remove($tmpFile); } + } - $loadedSheetNames = $spreadsheet->getSheetNames(); - $data = []; + /** + * @param mixed[] $data + * @return mixed[] + */ + private function transformSheetData(array $data): array + { + $labelledRows = []; + $headers = null; - foreach ($loadedSheetNames as $sheetIndex => $loadedSheetName) { - $worksheet = $spreadsheet->getSheet($sheetIndex); - $sheetData = $worksheet->toArray(); + foreach ($data as $rowIndex => $cells) { + $rowIndex = (int) $rowIndex; + $isHeaderRow = ($headers === null); - if (0 === \count($sheetData)) { + if ($isHeaderRow) { + $headers = $this->processHeaders($cells); continue; } - if (false === $context[self::AS_COLLECTION_KEY]) { - $data[$loadedSheetName] = $sheetData; + $labelledRows[$rowIndex - 1] = $this->processCells($headers, $cells); + } + + return $labelledRows; + } + /** + * Process the header row + * + * @param mixed[] $cells + * @return mixed[] + */ + private function processHeaders(array $cells): array + { + $headers = []; + foreach ($cells as $key => $value) { + if (null === $value || '' === $value) { continue; } + $headers[$key] = $value; + } + return $headers; + } - $labelledRows = []; - $headers = null; - - foreach ($sheetData as $rowIndex => $cells) { - $rowIndex = (int)$rowIndex; - - if (null === $headers) { - $headers = []; - - foreach ($cells as $key => $value) { - if (null === $value || '' === $value) { - continue; - } - - $headers[$key] = $value; - unset($sheetData[$rowIndex][$key]); - } - - continue; - } + /** + * Process the data cells + * + * @param mixed[] $headers + * @param mixed[] $cells + * @return mixed[] + */ + private function processCells(array $headers, array $cells): array + { + $labelledRow = []; + foreach ($cells as $key => $value) { + if (\array_key_exists($key, $headers)) { + $labelledRow[(string) $headers[$key]] = $value; + } else { + $labelledRow[''][$key] = $value; + } + } + return $labelledRow; + } - foreach ($cells as $key => $value) { - if (\array_key_exists($key, $headers)) { - $labelledRows[$rowIndex - 1][(string)$headers[$key]] = $value; - } else { - $labelledRows[$rowIndex - 1][''][$key] = $value; - } + /** + * @param mixed[] $context + * @return mixed[] + */ + public function decode(string $data, string $format, array $context = []): array + { + $context = $this->normalizeContext($context); + $tmpFile = (string) tempnam(sys_get_temp_dir(), $format); + $this->filesystem->dumpFile($tmpFile, $data); - unset($sheetData[$rowIndex][$key]); - } + $spreadsheet = $this->loadSpreadsheet($tmpFile, $format); + $loadedSheetNames = $spreadsheet->getSheetNames(); - unset($sheetData[$rowIndex]); + $data = []; + foreach ($loadedSheetNames as $sheetIndex => $loadedSheetName) { + $worksheet = $spreadsheet->getSheet($sheetIndex); + $sheetData = $worksheet->toArray(); + if (0 === \count($sheetData)) { + continue; } - $data[$loadedSheetName] = $labelledRows; + $data[$loadedSheetName] = !$context[self::AS_COLLECTION_KEY] ? + $sheetData : + $this->transformSheetData($sheetData); } - return $data; } /** + * @param array $result + * @param iterable $data + * * @throws NotNormalizableValueException when a value is not valid * @internal * @@ -339,7 +380,11 @@ private function flatten(iterable $data, array &$result, string $keySeparator, s ); } - $result[sprintf('="%s"', $newKey)] = false === $value ? 0 : (true === $value ? 1 : $value); + $result[sprintf('="%s"', $newKey)] = match ($value) { + false => 0, + true => 1, + default => $value, + }; } } @@ -352,18 +397,18 @@ private function flatten(iterable $data, array &$result, string $keySeparator, s private function normalizeContext(array $context = []): array { return [ - self::AS_COLLECTION_KEY => (bool)$this->getContextValue($context, self::AS_COLLECTION_KEY), - self::FLATTENED_HEADERS_SEPARATOR_KEY => (string)$this->getContextValue( + self::AS_COLLECTION_KEY => (bool) $this->getContextValue($context, self::AS_COLLECTION_KEY), + self::FLATTENED_HEADERS_SEPARATOR_KEY => (string) $this->getContextValue( $context, self::FLATTENED_HEADERS_SEPARATOR_KEY ), - self::HEADERS_IN_BOLD_KEY => (bool)$this->getContextValue($context, self::HEADERS_IN_BOLD_KEY), - self::HEADERS_HORIZONTAL_ALIGNMENT_KEY => (string)$this->getContextValue( + self::HEADERS_IN_BOLD_KEY => (bool) $this->getContextValue($context, self::HEADERS_IN_BOLD_KEY), + self::HEADERS_HORIZONTAL_ALIGNMENT_KEY => (string) $this->getContextValue( $context, self::HEADERS_HORIZONTAL_ALIGNMENT_KEY ), - self::COLUMNS_AUTOSIZE_KEY => (bool)$this->getContextValue($context, self::COLUMNS_AUTOSIZE_KEY), - self::COLUMNS_MAXSIZE_KEY => (int)$this->getContextValue($context, self::COLUMNS_MAXSIZE_KEY), + self::COLUMNS_AUTOSIZE_KEY => (bool) $this->getContextValue($context, self::COLUMNS_AUTOSIZE_KEY), + self::COLUMNS_MAXSIZE_KEY => (int) $this->getContextValue($context, self::COLUMNS_MAXSIZE_KEY), ]; } diff --git a/tests/ExcelEncoderTest.php b/tests/ExcelEncoderTest.php index e621dd5..c3d93c0 100755 --- a/tests/ExcelEncoderTest.php +++ b/tests/ExcelEncoderTest.php @@ -33,123 +33,84 @@ protected function setUp(): void $this->encoder = new ExcelEncoder(); } - public static function dataEncodingProvider(): array + /** + * @dataProvider provideDataEncoding + */ + public function testEncode(string $format): void { - return [ - [ExcelEncoder::XLS], - [ExcelEncoder::XLSX], - ]; + self::expectNotToPerformAssertions(); + $this->encoder->encode($this->getInitialData(), $format); } /** - * @dataProvider dataEncodingProvider + * @dataProvider provideDataDecoding + * + * @param mixed[] $result */ - public function testEncode(string $format): void + public function testDecode(string $file, string $format, array $result): void { - $contents = $this->encoder->encode($this->getInitialData(), $format); - static::assertIsString('string', $contents); + static::assertSame($result, $this->encoder->decode((string) file_get_contents($file), $format)); } - public static function dataDecodingProvider(): array + /** + * @return string[][] + */ + public static function provideDataEncoding(): array { return [ - [ - __DIR__ . '/Resources/encoded.xls', - ExcelEncoder::XLS, - [ - 'Sheet_0' => [ - [ - 'bool' => 0.0, - 'int' => 1, - 'float' => 1.618, - 'string' => 'Hello', - 'object.date' => '2000-01-01 13:37:00.000000', - 'object.timezone_type' => 3, - 'object.timezone' => 'Europe/Berlin', - 'array.bool' => 1, - 'array.int' => 3, - 'array.float' => 3.14, - 'array.string' => 'World', - 'array.object.date' => '2000-01-01 13:37:00.000000', - 'array.object.timezone_type' => 3, - 'array.object.timezone' => 'Europe/Berlin', - 'array.array.0' => 'again', - ], - ], - 'Feuil1' => [ - [ - 'bool' => 0.0, - 'int' => 1, - 'float' => 1.618, - 'string' => 'Hello', - 'object.date' => '2000-01-01 13:37:00.000000', - 'object.timezone_type' => 3, - 'object.timezone' => 'Europe/Berlin', - 'array.bool' => 1, - 'array.int' => 3, - 'array.float' => 3.14, - 'array.string' => 'World', - 'array.object.date' => '2000-01-01 13:37:00.000000', - 'array.object.timezone_type' => 3, - 'array.object.timezone' => 'Europe/Berlin', - 'array.array.0' => 'again', - ], - ], - ], - ], - [ - __DIR__ . '/Resources/encoded.xlsx', - ExcelEncoder::XLSX, - [ - 'Sheet_0' => [ - [ - 'bool' => 0, - 'int' => 1, - 'float' => 1.618, - 'string' => 'Hello', - 'object.date' => '2000-01-01 13:37:00.000000', - 'object.timezone_type' => 3, - 'object.timezone' => 'Europe/Berlin', - 'array.bool' => 1, - 'array.int' => 3, - 'array.float' => 3.14, - 'array.string' => 'World', - 'array.object.date' => '2000-01-01 13:37:00.000000', - 'array.object.timezone_type' => 3, - 'array.object.timezone' => 'Europe/Berlin', - 'array.array.0' => 'again', - ], - ], - 'Feuil1' => [ - [ - 'bool' => 0, - 'int' => 1, - 'float' => 1.618, - 'string' => 'Hello', - 'object.date' => '2000-01-01 13:37:00.000000', - 'object.timezone_type' => 3, - 'object.timezone' => 'Europe/Berlin', - 'array.bool' => 1, - 'array.int' => 3, - 'array.float' => 3.14, - 'array.string' => 'World', - 'array.object.date' => '2000-01-01 13:37:00.000000', - 'array.object.timezone_type' => 3, - 'array.object.timezone' => 'Europe/Berlin', - 'array.array.0' => 'again', - ], - ], - ], - ], + [ExcelEncoder::XLS], + [ExcelEncoder::XLSX], + ]; + } + + public static function provideDataDecoding(): array + { + $encodedFiles = [ + ['fileFormat' => 'xls', 'type' => ExcelEncoder::XLS], + ['fileFormat' => 'xlsx', 'type' => ExcelEncoder::XLSX], ]; + + $result = []; + + foreach ($encodedFiles as $encodedFile) { + $decodedCell = self::getDecodedCells($encodedFile['type']); + + $result[] = [ + sprintf('%s/Resources/encoded.%s', __DIR__, $encodedFile['fileFormat']), + $encodedFile['type'], + ['Sheet_0' => [$decodedCell], 'Feuil1' => [$decodedCell]], + ]; + } + + return $result; } /** - * @dataProvider dataDecodingProvider + * @return mixed[] */ - public function testDecode(string $file, string $format, array $result): void + private static function getDecodedCells(string $excelFormat): array { - static::assertSame($result, $this->encoder->decode((string)file_get_contents($file), $format)); + return [ + 'bool' => match ($excelFormat) { + ExcelEncoder::XLS => 0, + ExcelEncoder::XLSX => 0.0, + default => throw new \InvalidArgumentException('Invalid Excel format: ' . $excelFormat) + }, + 'int' => 1, + 'float' => 1.618, + 'string' => 'Hello', + 'object.date' => '2000-01-01 13:37:00.000000', + 'object.timezone_type' => 3, + 'object.timezone' => 'Europe/Berlin', + 'array.bool' => 1, + 'array.int' => 3, + 'array.float' => 3.14, + 'array.string' => 'World', + 'array.object.date' => '2000-01-01 13:37:00.000000', + 'array.object.timezone_type' => 3, + 'array.object.timezone' => 'Europe/Berlin', + 'array.array.0' => 'again', + ]; } /** @@ -160,19 +121,19 @@ private function getInitialData(): array return [ 'Sheet_0' => [ [ - 'bool' => false, - 'int' => 1, - 'float' => 1.618, - 'string' => 'Hello', - 'object' => new \DateTime('2000-01-01 13:37:00'), + 'bool' => true, + 'int' => 2, + 'float' => 2.718, + 'string' => 'Bonjour', + 'object' => new \DateTime('2021-05-21 10:15:00'), 'array' => [ - 'bool' => true, - 'int' => 3, - 'float' => 3.14, - 'string' => 'World', - 'object' => new \DateTime('2000-01-01 13:37:00'), + 'bool' => false, + 'int' => 5, + 'float' => 2.71, + 'string' => 'Monde', + 'object' => new \DateTime('2021-05-21 10:15:00'), 'array' => [ - 'again', + 'encore', ], ], ], @@ -180,18 +141,18 @@ private function getInitialData(): array 'Feuil1' => [ [ 'bool' => false, - 'int' => 1, - 'float' => 1.618, - 'string' => 'Hello', - 'object' => new \DateTime('2000-01-01 13:37:00'), + 'int' => 3, + 'float' => 3.141, + 'string' => 'Salut', + 'object' => new \DateTime('1999-12-31 23:59:59'), 'array' => [ 'bool' => true, - 'int' => 3, - 'float' => 3.14, - 'string' => 'World', - 'object' => new \DateTime('2000-01-01 13:37:00'), + 'int' => 7, + 'float' => 1.61, + 'string' => 'Terre', + 'object' => new \DateTime('1999-12-31 23:59:59'), 'array' => [ - 'again', + 'toujours', ], ], ], From 36d1dd76565d5551acad7f4a51d4e16d91621957 Mon Sep 17 00:00:00 2001 From: Florian Guimier Date: Fri, 20 Dec 2024 15:10:20 +0100 Subject: [PATCH 3/3] Revert "Revert "fix"" This reverts commit ab1fb6a3f0915b218504a4fd9a5a8a83cef98323. --- tests/ExcelEncoderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ExcelEncoderTest.php b/tests/ExcelEncoderTest.php index c3d93c0..799eefa 100755 --- a/tests/ExcelEncoderTest.php +++ b/tests/ExcelEncoderTest.php @@ -92,8 +92,8 @@ private static function getDecodedCells(string $excelFormat): array { return [ 'bool' => match ($excelFormat) { - ExcelEncoder::XLS => 0, - ExcelEncoder::XLSX => 0.0, + ExcelEncoder::XLS => 0.0, + ExcelEncoder::XLSX => 0, default => throw new \InvalidArgumentException('Invalid Excel format: ' . $excelFormat) }, 'int' => 1,