diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..e4035e2 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: tiamo +# patreon: tiamo diff --git a/.gitignore b/.gitignore index dcb25fa..3f2211a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,12 @@ /vendor -/.idea /tests/tmp /tmp /nbproject/* *.DS_Store .idea .env +coverage.xml .phpunit.result.cache +.php_cs.cache +*.swp +*.swo diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..4277bb1 --- /dev/null +++ b/.php_cs @@ -0,0 +1,28 @@ +in(__DIR__ . DIRECTORY_SEPARATOR . 'tests') + ->in(__DIR__ . DIRECTORY_SEPARATOR . 'src') + ->append(['.php_cs']); + +$rules = [ + '@Symfony' => true, + 'phpdoc_no_empty_return' => false, + 'array_syntax' => ['syntax' => 'short'], + 'yoda_style' => false, + 'binary_operator_spaces' => [ + 'operators' => [ + '=>' => 'align', + '=' => 'align', + ], + ], + 'concat_space' => ['spacing' => 'one'], + 'not_operator_with_space' => false, +]; + +$rules['increment_style'] = ['style' => 'post']; + +return PhpCsFixer\Config::create() + ->setUsingCache(true) + ->setRules($rules) + ->setFinder($finder); diff --git a/.php_cs.dist b/.php_cs.dist deleted file mode 100644 index 670bb81..0000000 --- a/.php_cs.dist +++ /dev/null @@ -1,29 +0,0 @@ -setRiskyAllowed(true) - ->setRules(array( - '@Symfony' => true, - '@Symfony:risky' => true, - 'array_syntax' => true, - 'concat_space' => ['spacing' => 'one'], - 'is_null' => ['use_yoda_style' => false], - 'no_php4_constructor' => true, - 'no_short_echo_tag' => true, - 'no_unreachable_default_argument_value' => true, - 'no_useless_return' => true, - 'ordered_imports' => true, - 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], - 'phpdoc_align' => false, - 'phpdoc_order' => true, - 'pre_increment' => false, - 'protected_to_private' => false, - )) - ->setCacheFile(__DIR__ . '/.php_cs.cache') - ->setFinder(PhpCsFixer\Finder::create() - ->exclude('vendor') - ->exclude('cache') - ->exclude('tmp') - ->in(__DIR__) - ) -; diff --git a/.travis.yml b/.travis.yml index f2f0695..b71ec88 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,21 @@ -dist: trusty language: php +sudo: false + php: - 5.5 - 5.6 - 7.0 - 7.1 -#before_install: -#- if [[ ${TRAVIS_PHP_VERSION:0:3} == "5.5" ]]; then composer require --dev --no-update phpunit/phpunit ~4; fi - -install: -- composer install --no-interaction --no-suggest +env: + matrix: + - COMPOSER_FLAGS="--prefer-lowest" + - COMPOSER_FLAGS="" before_script: -- phpenv config-rm xdebug.ini + - travis_retry composer self-update + - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source script: -- ./vendor/bin/phing all + - composer test diff --git a/CHANGELOG.md b/CHANGELOG.md index 8004bf7..576a2b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # Changelog -## VERSION 2.1.* +## 2.2.0 + +2020-06-27 + ++ Full code refactory ++ Fixed tests + +## 2.1.* 2018-10 diff --git a/README.md b/README.md index 0500e7b..767a797 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ # SPSS / PSPP -A PHP library for reading and writing SPSS / PSPP .sav data files. - -VERSION 2.1.0 ([CHANGELOG](CHANGELOG.md)) - [![Latest Version on Packagist](https://img.shields.io/packagist/v/tiamo/spss.svg?style=flat-square)](https://packagist.org/packages/tiamo/spss) [![Build Status](https://travis-ci.org/tiamo/spss.svg?branch=master)](https://travis-ci.org/tiamo/spss) [![Total Downloads](https://img.shields.io/packagist/dt/tiamo/spss.svg?style=flat-square)](https://packagist.org/packages/tiamo/spss) +A PHP library for reading and writing SPSS / PSPP .sav data files. + ## Requirements + php >= 5.5 @@ -16,77 +14,14 @@ VERSION 2.1.0 ([CHANGELOG](CHANGELOG.md)) ## Installation -The preferred way to install this extension is through [composer](http://getcomposer.org/download/). - -Either run - ``` composer require tiamo/spss ``` -or add - -``` -"tiamo/spss": "*" -``` - -to the require section of your `composer.json` [file](https://packagist.org/packages/tiamo/spss) -or download from [here](https://github.com/tiamo/spss/releases). - ## Usage -Reader example: - -```php -// Initialize reader -$reader = \SPSS\Reader::fromFile('path/to/file.sav'); - -// Read header data -$reader->readHeader(); -// var_dump($reader->header); - -// Read full data -$reader->read(); -// var_dump($reader->variables); -// var_dump($reader->valueLabels); -// var_dump($reader->documents); -// var_dump($reader->data); -``` -or -```php -$reader = \SPSS\Reader::fromString(file_get_contents('path/to/file.sav'))->read(); -``` - -Writer example: - -```php -$writer = new \SPSS\Writer([ - 'header' => [ - 'prodName' => '@(#) SPSS DATA FILE test', - 'layoutCode' => 2, - 'compression' => 1, - 'weightIndex' => 0, - 'bias' => 100, - 'creationDate' => '01 Feb 01', - 'creationTime' => '01:01:01', - ], - 'variables' => [ - [ - 'name' => 'VAR1', - 'width' => 0, - 'decimals' => 0 - 'format' => 5, - 'columns' => 50, - 'align' => 1, - 'measure' => 1, - 'data' => [ - 1, 2, 3 - ], - ], - ... - ] -]); -``` +* [Documentation](./docs/index.md) +* [Examples](./examples) ## Changelog diff --git a/build.xml b/build.xml deleted file mode 100644 index c29af9e..0000000 --- a/build.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/composer.json b/composer.json index f6150b0..cce48a9 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,6 @@ "email": "vk.tiamo@gmail.com" } ], - "minimum-stability": "dev", - "prefer-stable": true, "require": { "php": ">=5.5", "ext-mbstring": "*", @@ -30,11 +28,14 @@ "ext-json": "*" }, "require-dev": { - "phing/phing": "^2", + "ergebnis/phpstan-rules": "^0.15.0", + "friendsofphp/php-cs-fixer": "^2.16", + "phpstan/phpstan": "^0.12.31", + "phpstan/phpstan-strict-rules": "^0.12.2", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "doctrine/instantiator": "1.0.5", - "phpdocumentor/reflection-docblock": "3.0.2", - "squizlabs/php_codesniffer": "^3" + "rector/rector": "^0.7.41", + "squizlabs/php_codesniffer": "^3", + "thecodingmachine/phpstan-strict-rules": "^0.12.0" }, "autoload": { "psr-4": { @@ -46,11 +47,21 @@ "SPSS\\Tests\\": "tests/" } }, + "minimum-stability": "dev", + "prefer-stable": true, "config": { - "sort-packages": true + "sort-packages": true, + "preferred-install": "dist" }, "scripts": { - "test": "phpunit --verbose", - "codestyle": "php-cs-fixer fix --path-mode=intersection --config=.php_cs.dist" + "lint": "rector process src && php-cs-fixer fix -v", + "test:lint": "php-cs-fixer fix -v --dry-run && rector process src --dry-run", + "test:types": "phpstan analyse --ansi --memory-limit=0", + "test:unit": "phpunit --no-coverage", + "test": [ + "@test:lint", + "@test:types", + "@test:unit" + ] } } diff --git a/composer.lock b/composer.lock index 0bb97aa..b0de644 100644 --- a/composer.lock +++ b/composer.lock @@ -4,42 +4,45 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b4bd362ea25f923fbac704d1743e53bb", + "content-hash": "4cde024d710d08e82aa974a17171c6ce", "packages": [], "packages-dev": [ { - "name": "doctrine/instantiator", - "version": "1.0.5", + "name": "composer/package-versions-deprecated", + "version": "1.8.1", "source": { "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "b9805885293f3957ee0dd42616ac6915c4ac9a4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b9805885293f3957ee0dd42616ac6915c4ac9a4b", + "reference": "b9805885293f3957ee0dd42616ac6915c4ac9a4b", "shasum": "" }, "require": { - "php": ">=5.3,<8.0-DEV" + "composer-plugin-api": "^1.1.0 || ^2.0", + "php": "^7" + }, + "replace": { + "ocramius/package-versions": "1.8.99" }, "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "composer/composer": "^1.9.3 || ^2.0@dev", + "ext-zip": "^1.13", + "phpunit/phpunit": "^6.5 || ^7" }, - "type": "library", + "type": "composer-plugin", "extra": { + "class": "PackageVersions\\Installer", "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + "PackageVersions\\": "src/PackageVersions" } }, "notification-url": "https://packagist.org/downloads/", @@ -49,292 +52,345 @@ "authors": [ { "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "email": "ocramius@gmail.com" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" } ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } ], - "time": "2015-06-14T21:17:01+00:00" + "time": "2020-06-19T07:59:31+00:00" }, { - "name": "myclabs/deep-copy", - "version": "1.9.5", + "name": "composer/semver", + "version": "1.5.1", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef" + "url": "https://github.com/composer/semver.git", + "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef", - "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef", + "url": "https://api.github.com/repos/composer/semver/zipball/c6bea70230ef4dd483e6bbcab6005f682ed3a8de", + "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de", "shasum": "" }, "require": { - "php": "^7.1" - }, - "replace": { - "myclabs/deep-copy": "self.version" + "php": "^5.3.2 || ^7.0" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "phpunit/phpunit": "^4.5 || ^5.0.5" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, "autoload": { "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] + "Composer\\Semver\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "semantic", + "semver", + "validation", + "versioning" ], - "time": "2020-01-17T21:11:47+00:00" + "time": "2020-01-13T12:06:48+00:00" }, { - "name": "phar-io/manifest", - "version": "1.0.1", + "name": "composer/xdebug-handler", + "version": "1.4.2", "source": { "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51", + "reference": "fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" }, + "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" }, { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "url": "https://github.com/composer", + "type": "github" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" } ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" + "time": "2020-06-04T11:16:35+00:00" }, { - "name": "phar-io/version", - "version": "1.0.1", + "name": "doctrine/annotations", + "version": "1.10.3", "source": { "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + "url": "https://github.com/doctrine/annotations.git", + "reference": "5db60a4969eba0e0c197a19c077780aadbc43c5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/5db60a4969eba0e0c197a19c077780aadbc43c5d", + "reference": "5db60a4969eba0e0c197a19c077780aadbc43c5d", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "doctrine/lexer": "1.*", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^7.5" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9.x-dev" + } + }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "name": "Roman Borschel", + "email": "roman@code-factory.org" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2020-05-25T17:24:27+00:00" }, { - "name": "phing/phing", - "version": "2.16.3", + "name": "doctrine/inflector", + "version": "1.4.3", "source": { "type": "git", - "url": "https://github.com/phingofficial/phing.git", - "reference": "b34c2bf9cd6abd39b4287dee31e68673784c8567" + "url": "https://github.com/doctrine/inflector.git", + "reference": "4650c8b30c753a76bf44fb2ed00117d6f367490c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phingofficial/phing/zipball/b34c2bf9cd6abd39b4287dee31e68673784c8567", - "reference": "b34c2bf9cd6abd39b4287dee31e68673784c8567", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/4650c8b30c753a76bf44fb2ed00117d6f367490c", + "reference": "4650c8b30c753a76bf44fb2ed00117d6f367490c", "shasum": "" }, "require": { - "php": ">=5.2.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "ext-pdo_sqlite": "*", - "mikey179/vfsstream": "^1.6", - "pdepend/pdepend": "2.x", - "pear/archive_tar": "1.4.x", - "pear/http_request2": "dev-trunk", - "pear/net_growl": "dev-trunk", - "pear/pear-core-minimal": "1.10.1", - "pear/versioncontrol_git": "@dev", - "pear/versioncontrol_svn": "~0.5", - "phpdocumentor/phpdocumentor": "2.x", - "phploc/phploc": "~2.0.6", - "phpmd/phpmd": "~2.2", - "phpunit/phpunit": ">=3.7", - "sebastian/git": "~1.0", - "sebastian/phpcpd": "2.x", - "siad007/versioncontrol_hg": "^1.0", - "simpletest/simpletest": "^1.1", - "squizlabs/php_codesniffer": "~2.2", - "symfony/yaml": "^2.8 || ^3.1 || ^4.0" - }, - "suggest": { - "pdepend/pdepend": "PHP version of JDepend", - "pear/archive_tar": "Tar file management class", - "pear/versioncontrol_git": "A library that provides OO interface to handle Git repository", - "pear/versioncontrol_svn": "A simple OO-style interface for Subversion, the free/open-source version control system", - "phpdocumentor/phpdocumentor": "Documentation Generator for PHP", - "phploc/phploc": "A tool for quickly measuring the size of a PHP project", - "phpmd/phpmd": "PHP version of PMD tool", - "phpunit/php-code-coverage": "Library that provides collection, processing, and rendering functionality for PHP code coverage information", - "phpunit/phpunit": "The PHP Unit Testing Framework", - "sebastian/phpcpd": "Copy/Paste Detector (CPD) for PHP code", - "siad007/versioncontrol_hg": "A library for interfacing with Mercurial repositories.", - "tedivm/jshrink": "Javascript Minifier built in PHP" + "doctrine/coding-standard": "^7.0", + "phpstan/phpstan": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, - "bin": [ - "bin/phing" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.16.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { - "classmap": [ - "classes/phing/" - ] + "psr-4": { + "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector", + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "classes" - ], "license": [ - "LGPL-3.0-only" + "MIT" ], "authors": [ { - "name": "Michiel Rook", - "email": "mrook@php.net" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Phing Community", - "homepage": "https://www.phing.info/trac/wiki/Development/Contributors" + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "PHing Is Not GNU make; it's a PHP project build system or build tool based on Apache Ant.", - "homepage": "https://www.phing.info/", + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", "keywords": [ - "build", - "phing", - "task", - "tool" + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "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%2Finflector", + "type": "tidelift" + } ], - "time": "2020-02-03T18:50:54+00:00" + "time": "2020-05-29T07:19:59+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "name": "doctrine/instantiator", + "version": "1.3.1", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", + "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.1 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "doctrine/coding-standard": "^6.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", @@ -343,51 +399,64 @@ ], "authors": [ { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" } ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" + "constructor", + "instantiate" + ], + "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": "2017-09-11T18:02:19+00:00" + "time": "2020-05-29T17:27:14+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "3.0.2", + "name": "doctrine/lexer", + "version": "1.2.1", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "45ada3e3fd09789fbfbd6d65b3f0901f0030dc61" + "url": "https://github.com/doctrine/lexer.git", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/45ada3e3fd09789fbfbd6d65b3f0901f0030dc61", - "reference": "45ada3e3fd09789fbfbd6d65b3f0901f0030dc61", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", "shasum": "" }, "require": { - "php": ">=5.5", - "phpdocumentor/reflection-common": "^1.0@dev", - "phpdocumentor/type-resolver": "^0.1.5", - "webmozart/assert": "^1.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^4.4" + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan": "^0.11.8", + "phpunit/phpunit": "^8.2" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" } }, "notification-url": "https://packagist.org/downloads/", @@ -396,46 +465,89 @@ ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2016-06-06T06:44:13+00:00" + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "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%2Flexer", + "type": "tidelift" + } + ], + "time": "2020-05-25T17:44:05+00:00" }, { - "name": "phpdocumentor/type-resolver", - "version": "0.1.8", + "name": "ergebnis/phpstan-rules", + "version": "0.15.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9891754231e55d42f0d16988ffb799af39f31a12" + "url": "https://github.com/ergebnis/phpstan-rules.git", + "reference": "f0c49d0efdaebd9e663e9e5637253ebcc41048d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9891754231e55d42f0d16988ffb799af39f31a12", - "reference": "9891754231e55d42f0d16988ffb799af39f31a12", + "url": "https://api.github.com/repos/ergebnis/phpstan-rules/zipball/f0c49d0efdaebd9e663e9e5637253ebcc41048d7", + "reference": "f0c49d0efdaebd9e663e9e5637253ebcc41048d7", "shasum": "" }, "require": { - "php": ">=5.5", - "phpdocumentor/reflection-common": "^1.0" + "ext-mbstring": "*", + "nikic/php-parser": "^4.2.3", + "php": "^7.1", + "phpstan/phpstan": "~0.11.15 || ~0.12.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2" - }, - "type": "library", + "ergebnis/composer-normalize": "^2.5.1", + "ergebnis/license": "~1.0.0", + "ergebnis/php-cs-fixer-config": "^2.1.2", + "ergebnis/test-util": "~1.0.0", + "infection/infection": "~0.13.6", + "nette/di": "^3.0.1", + "phpstan/phpstan-deprecation-rules": "~0.11.2", + "phpstan/phpstan-strict-rules": "~0.11.1", + "phpunit/phpunit": "^7.5.20", + "psalm/plugin-phpunit": "~0.10.0", + "psr/container": "^1.0.0", + "vimeo/psalm": "^3.11.2", + "zendframework/zend-servicemanager": "^2.0.0" + }, + "type": "phpstan-extension", "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" + "phpstan": { + "includes": [ + "rules.neon" + ] } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "Ergebnis\\PHPStan\\Rules\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -444,47 +556,110 @@ ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Andreas Möller", + "email": "am@localheinz.com" } ], - "time": "2016-03-28T10:02:29+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.10.3", + "description": "Provides additional rules for phpstan/phpstan.", + "homepage": "https://github.com/ergebnis/phpstan-rules", + "keywords": [ + "PHPStan", + "phpstan-extreme-rules", + "phpstan-rules" + ], + "funding": [ + { + "url": "https://paypal.me/localheinz", + "type": "custom" + }, + { + "url": "https://www.amazon.de/hz/wishlist/ls/2NCHMSJ4BC1OW", + "type": "custom" + }, + { + "url": "https://www.buymeacoffee.com/localheinz", + "type": "custom" + }, + { + "url": "https://github.com/localheinz", + "type": "github" + } + ], + "time": "2020-05-10T18:39:28+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v2.16.3", "source": { "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "451c3cd1418cf640de218914901e51b064abb093" + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "83baf823a33a1cbd5416c8626935cf3f843c10b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", - "reference": "451c3cd1418cf640de218914901e51b064abb093", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/83baf823a33a1cbd5416c8626935cf3f843c10b0", + "reference": "83baf823a33a1cbd5416c8626935cf3f843c10b0", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" + "composer/semver": "^1.4", + "composer/xdebug-handler": "^1.2", + "doctrine/annotations": "^1.2", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^5.6 || ^7.0", + "php-cs-fixer/diff": "^1.3", + "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0", + "symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0", + "symfony/filesystem": "^3.0 || ^4.0 || ^5.0", + "symfony/finder": "^3.0 || ^4.0 || ^5.0", + "symfony/options-resolver": "^3.0 || ^4.0 || ^5.0", + "symfony/polyfill-php70": "^1.0", + "symfony/polyfill-php72": "^1.4", + "symfony/process": "^3.0 || ^4.0 || ^5.0", + "symfony/stopwatch": "^3.0 || ^4.0 || ^5.0" }, "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", + "justinrainbow/json-schema": "^5.0", + "keradus/cli-executor": "^1.2", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.1", + "php-cs-fixer/accessible-object": "^1.0", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.1", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.1", + "phpunitgoodpractices/traits": "^1.8", + "symfony/phpunit-bridge": "^4.3 || ^5.0", + "symfony/yaml": "^3.0 || ^4.0 || ^5.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10.x-dev" - } + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters in cache signature.", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", + "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", "autoload": { "psr-4": { - "Prophecy\\": "src/Prophecy" - } + "PhpCsFixer\\": "src/" + }, + "classmap": [ + "tests/Test/AbstractFixerTestCase.php", + "tests/Test/AbstractIntegrationCaseFactory.php", + "tests/Test/AbstractIntegrationTestCase.php", + "tests/Test/Assert/AssertTokensTrait.php", + "tests/Test/IntegrationCase.php", + "tests/Test/IntegrationCaseFactory.php", + "tests/Test/IntegrationCaseFactoryInterface.php", + "tests/Test/InternalIntegrationCaseFactory.php", + "tests/Test/IsIdenticalConstraint.php", + "tests/TestCase.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -492,155 +667,198 @@ ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" } ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" + "description": "A tool to automatically fix PHP code style", + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } ], - "time": "2020-03-05T15:02:03+00:00" + "time": "2020-04-15T18:51:10+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "6.0.5", + "name": "jean85/pretty-package-versions", + "version": "1.5.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "4cab20a326d14de7575a8e235c70d879b569a57a" + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "e9f4324e88b8664be386d90cf60fbc202e1f7fc9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4cab20a326d14de7575a8e235c70d879b569a57a", - "reference": "4cab20a326d14de7575a8e235c70d879b569a57a", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/e9f4324e88b8664be386d90cf60fbc202e1f7fc9", + "reference": "e9f4324e88b8664be386d90cf60fbc202e1f7fc9", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.1", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" + "composer/package-versions-deprecated": "^1.8.0", + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "suggest": { - "ext-xdebug": "^2.6.0" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.0-dev" + "dev-master": "1.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Jean85\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "description": "A wrapper for ocramius/package-versions to get pretty versions strings", "keywords": [ - "coverage", - "testing", - "xunit" + "composer", + "package", + "release", + "versions" ], - "time": "2018-05-28T11:49:20+00:00" + "time": "2020-06-23T06:23:06+00:00" }, { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", + "name": "jetbrains/phpstorm-stubs", + "version": "v2019.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + "url": "https://github.com/JetBrains/phpstorm-stubs.git", + "reference": "883b6facd78e01c0743b554af86fa590c2573f40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/883b6facd78e01c0743b554af86fa590c2573f40", + "reference": "883b6facd78e01c0743b554af86fa590c2573f40", "shasum": "" }, - "require": { - "php": ">=5.3.3" + "require-dev": { + "nikic/php-parser": "^4", + "php": "^7.1", + "phpdocumentor/reflection-docblock": "^4.3", + "phpunit/phpunit": "^7" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "files": [ + "PhpStormStubsMap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "Apache-2.0" ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } + "description": "PHP runtime & extensions header files for PhpStorm", + "homepage": "https://www.jetbrains.com/phpstorm", + "keywords": [ + "autocomplete", + "code", + "inference", + "inspection", + "jetbrains", + "phpstorm", + "stubs", + "type" ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "time": "2019-12-05T16:56:26+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.9.5", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef", + "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", "keywords": [ - "filesystem", - "iterator" + "clone", + "copy", + "duplicate", + "object", + "object graph" ], - "time": "2017-11-27T13:52:08+00:00" + "time": "2020-01-17T21:11:47+00:00" }, { - "name": "phpunit/php-text-template", - "version": "1.2.1", + "name": "nette/finder", + "version": "v2.5.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + "url": "https://github.com/nette/finder.git", + "reference": "4ad2c298eb8c687dd0e74ae84206a4186eeaed50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "url": "https://api.github.com/repos/nette/finder/zipball/4ad2c298eb8c687dd0e74ae84206a4186eeaed50", + "reference": "4ad2c298eb8c687dd0e74ae84206a4186eeaed50", "shasum": "" }, "require": { - "php": ">=5.3.3" + "nette/utils": "^2.4 || ^3.0", + "php": ">=7.1" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "phpstan/phpstan": "^0.12", + "tracy/tracy": "^2.3" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -648,46 +866,59 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "🔍 Nette Finder: find files and directories with an intuitive API.", + "homepage": "https://nette.org", "keywords": [ - "template" + "filesystem", + "glob", + "iterator", + "nette" ], - "time": "2015-06-21T13:50:34+00:00" + "time": "2020-01-03T20:35:40+00:00" }, { - "name": "phpunit/php-timer", - "version": "2.1.2", + "name": "nette/robot-loader", + "version": "v3.2.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + "url": "https://github.com/nette/robot-loader.git", + "reference": "726c462e73e739e965ec654a667407074cfe83c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/726c462e73e739e965ec654a667407074cfe83c0", + "reference": "726c462e73e739e965ec654a667407074cfe83c0", "shasum": "" }, "require": { - "php": "^7.1" + "ext-tokenizer": "*", + "nette/finder": "^2.5 || ^3.0", + "nette/utils": "^3.0", + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "nette/tester": "^2.0", + "phpstan/phpstan": "^0.12", + "tracy/tracy": "^2.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -697,42 +928,61 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", "keywords": [ - "timer" + "autoload", + "class", + "interface", + "nette", + "trait" ], - "time": "2019-06-07T04:22:29+00:00" + "time": "2020-02-28T13:10:07+00:00" }, { - "name": "phpunit/php-token-stream", - "version": "3.1.1", + "name": "nette/utils", + "version": "v3.1.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + "url": "https://github.com/nette/utils.git", + "reference": "488f58378bba71767e7831c83f9e0fa808bf83b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", - "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", + "url": "https://api.github.com/repos/nette/utils/zipball/488f58378bba71767e7831c83f9e0fa808bf83b9", + "reference": "488f58378bba71767e7831c83f9e0fa808bf83b9", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "nette/tester": "~2.0", + "phpstan/phpstan": "^0.12", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" }, "type": "library", "extra": { @@ -747,80 +997,75 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", "keywords": [ - "tokenizer" + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" ], - "time": "2019-09-17T06:23:10+00:00" + "time": "2020-05-27T09:58:51+00:00" }, { - "name": "phpunit/phpunit", - "version": "7.1.5", + "name": "nikic/php-parser", + "version": "v4.5.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "ca64dba53b88aba6af32aebc6b388068db95c435" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "53c2753d756f5adb586dca79c2ec0e2654dd9463" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ca64dba53b88aba6af32aebc6b388068db95c435", - "reference": "ca64dba53b88aba6af32aebc6b388068db95c435", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/53c2753d756f5adb586dca79c2ec0e2654dd9463", + "reference": "53c2753d756f5adb586dca79c2ec0e2654dd9463", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.1", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.1", - "phpunit/php-file-iterator": "^1.4.3", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.0", - "phpunit/phpunit-mock-objects": "^6.1.1", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0.1" + "ext-tokenizer": "*", + "php": ">=7.0" }, "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0" + "ircmaxell/php-yacc": "0.0.5", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" }, "bin": [ - "phpunit" + "bin/php-parse" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "7.1-dev" + "dev-master": "4.3-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -828,148 +1073,152 @@ ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nikita Popov" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", + "description": "A PHP parser written in PHP", "keywords": [ - "phpunit", - "testing", - "xunit" + "parser", + "php" ], - "time": "2018-04-29T15:09:19+00:00" + "time": "2020-06-03T07:24:19+00:00" }, { - "name": "phpunit/phpunit-mock-objects", - "version": "6.1.2", + "name": "ondram/ci-detector", + "version": "3.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "f9756fd4f43f014cb2dca98deeaaa8ce5500a36e" + "url": "https://github.com/OndraM/ci-detector.git", + "reference": "0babf1cb71984f652498c6327a47d0081cd1e01b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/f9756fd4f43f014cb2dca98deeaaa8ce5500a36e", - "reference": "f9756fd4f43f014cb2dca98deeaaa8ce5500a36e", + "url": "https://api.github.com/repos/OndraM/ci-detector/zipball/0babf1cb71984f652498c6327a47d0081cd1e01b", + "reference": "0babf1cb71984f652498c6327a47d0081cd1e01b", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.1", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "suggest": { - "ext-soap": "*" + "ergebnis/composer-normalize": "^2.2", + "lmc/coding-standard": "^1.3 || ^2.0", + "php-coveralls/php-coveralls": "^2.2", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpstan/extension-installer": "^1.0.3", + "phpstan/phpstan": "^0.12.0", + "phpstan/phpstan-phpunit": "^0.12.1", + "phpunit/phpunit": "^7.1 || ^8.0 || ^9.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.1-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "OndraM\\CiDetector\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Ondřej Machulda", + "email": "ondrej.machulda@gmail.com" } ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "description": "Detect continuous integration environment and provide unified access to properties of current build", "keywords": [ - "mock", - "xunit" + "CircleCI", + "Codeship", + "adapter", + "appveyor", + "aws", + "aws codebuild", + "bamboo", + "bitbucket", + "buddy", + "codebuild", + "continuous integration", + "continuousphp", + "drone", + "github", + "gitlab", + "interface", + "jenkins", + "teamcity", + "travis" ], - "abandoned": true, - "time": "2018-05-29T13:54:20+00:00" + "time": "2020-05-11T19:24:44+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", + "name": "paragonie/random_compat", + "version": "v9.99.99", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7" }, "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" }, - "autoload": { - "classmap": [ - "src/" - ] + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." }, + "type": "library", "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" } ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2018-07-02T15:55:56+00:00" }, { - "name": "sebastian/comparator", - "version": "3.0.2", + "name": "phar-io/manifest", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", "shasum": "" }, "require": { - "php": "^7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.1" + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { @@ -983,58 +1232,42 @@ ], "authors": [ { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" }, { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" }, { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2018-07-12T15:12:46+00:00" + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" }, { - "name": "sebastian/diff", - "version": "3.0.2", + "name": "phar-io/version", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", "shasum": "" }, "require": { - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.0", - "symfony/process": "^2 || ^3.3 || ^4" + "php": "^5.6 || ^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, "autoload": { "classmap": [ "src/" @@ -1046,50 +1279,46 @@ ], "authors": [ { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" + "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" + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "time": "2019-02-04T06:01:07+00:00" + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" }, { - "name": "sebastian/environment", - "version": "3.1.0", + "name": "php-cs-fixer/diff", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + "url": "https://github.com/PHP-CS-Fixer/diff.git", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756", + "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^6.1" + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "symfony/process": "^3.3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, "autoload": { "classmap": [ "src/" @@ -1100,456 +1329,4494 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "SpacePossum" } ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "description": "sebastian/diff v2 backport support for PHP5.6", + "homepage": "https://github.com/PHP-CS-Fixer", "keywords": [ - "Xdebug", - "environment", - "hhvm" + "diff" ], - "time": "2017-07-01T08:51:00+00:00" + "time": "2018-02-15T16:58:55+00:00" }, { - "name": "sebastian/exporter", - "version": "3.1.2", + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-2.x": "2.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", + "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", + "shasum": "" + }, + "require": { + "ext-filter": "^7.1", + "php": "^7.2", + "phpdocumentor/reflection-common": "^2.0", + "phpdocumentor/type-resolver": "^1.0", + "webmozart/assert": "^1" + }, + "require-dev": { + "doctrine/instantiator": "^1", + "mockery/mockery": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2020-02-22T12:28:44+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", + "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2020-06-27T10:12:23+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.10.3", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "451c3cd1418cf640de218914901e51b064abb093" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", + "reference": "451c3cd1418cf640de218914901e51b064abb093", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", + "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5 || ^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2020-03-05T15:02:03+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "0.4.8", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "1948aa842a94170b408963a9768a102f19cbf1b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1948aa842a94170b408963a9768a102f19cbf1b7", + "reference": "1948aa842a94170b408963a9768a102f19cbf1b7", + "shasum": "" + }, + "require": { + "php": "~7.1" + }, + "require-dev": { + "consistence/coding-standard": "^3.5", + "ergebnis/composer-normalize": "^2.0.2", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.26", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^6.3", + "slevomat/coding-standard": "^4.7.2", + "symfony/process": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.4-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "time": "2020-06-10T05:04:41+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "0.12.31", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "776c8056b401e1b67f277b9e9fb334d1a274671d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/776c8056b401e1b67f277b9e9fb334d1a274671d", + "reference": "776c8056b401e1b67f277b9e9fb334d1a274671d", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.12-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpstan", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2020-06-24T20:55:29+00:00" + }, + { + "name": "phpstan/phpstan-phpunit", + "version": "0.12.11", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-phpunit.git", + "reference": "ab783a8ea634ea23305a8818c4750603e714489b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/ab783a8ea634ea23305a8818c4750603e714489b", + "reference": "ab783a8ea634ea23305a8818c4750603e714489b", + "shasum": "" + }, + "require": { + "php": "~7.1", + "phpstan/phpstan": "^0.12.20" + }, + "conflict": { + "phpunit/phpunit": "<7.0" + }, + "require-dev": { + "consistence/coding-standard": "^3.5", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ergebnis/composer-normalize": "^2.0.2", + "jakub-onderka/php-parallel-lint": "^1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "satooshi/php-coveralls": "^1.0", + "slevomat/coding-standard": "^4.7.2" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "0.12-dev" + }, + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPUnit extensions and rules for PHPStan", + "time": "2020-06-01T16:43:31+00:00" + }, + { + "name": "phpstan/phpstan-strict-rules", + "version": "0.12.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-strict-rules.git", + "reference": "a670a59aff7cf96f75d21b974860ada10e25b2ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/a670a59aff7cf96f75d21b974860ada10e25b2ee", + "reference": "a670a59aff7cf96f75d21b974860ada10e25b2ee", + "shasum": "" + }, + "require": { + "php": "~7.1", + "phpstan/phpstan": "^0.12.6" + }, + "require-dev": { + "consistence/coding-standard": "^3.0.1", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ergebnis/composer-normalize": "^2.0.2", + "jakub-onderka/php-parallel-lint": "^1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0", + "slevomat/coding-standard": "^4.5.2" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "0.12-dev" + }, + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Extra strict and opinionated rules for PHPStan", + "time": "2020-01-20T13:08:52+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "6.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "4cab20a326d14de7575a8e235c70d879b569a57a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4cab20a326d14de7575a8e235c70d879b569a57a", + "reference": "4cab20a326d14de7575a8e235c70d879b569a57a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.1", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-xdebug": "^2.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "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" + ], + "time": "2018-05-28T11:49:20+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.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" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "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" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2019-06-07T04:22:29+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "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" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2019-09-17T06:23:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "7.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "ca64dba53b88aba6af32aebc6b388068db95c435" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ca64dba53b88aba6af32aebc6b388068db95c435", + "reference": "ca64dba53b88aba6af32aebc6b388068db95c435", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0.1", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.0", + "phpunit/phpunit-mock-objects": "^6.1.1", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.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": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-04-29T15:09:19+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "6.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "f9756fd4f43f014cb2dca98deeaaa8ce5500a36e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/f9756fd4f43f014cb2dca98deeaaa8ce5500a36e", + "reference": "f9756fd4f43f014cb2dca98deeaaa8ce5500a36e", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "php": "^7.1", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.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": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "abandoned": true, + "time": "2018-05-29T13:54:20+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2020-03-23T09:12:05+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "rector/rector", + "version": "v0.7.41", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "a1a2df1e8319094a2e6370e6dd187f8891936b18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/a1a2df1e8319094a2e6370e6dd187f8891936b18", + "reference": "a1a2df1e8319094a2e6370e6dd187f8891936b18", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.4", + "doctrine/annotations": "^1.10.2", + "doctrine/inflector": "^1.3", + "ext-json": "*", + "jean85/pretty-package-versions": "^1.2", + "jetbrains/phpstorm-stubs": "^2019.3", + "nette/robot-loader": "^3.2", + "nette/utils": "^3.1", + "nikic/php-parser": "^4.5", + "ondram/ci-detector": "^3.4", + "php": "^7.2.4", + "phpstan/phpdoc-parser": "^0.4.7", + "phpstan/phpstan": "^0.12.25", + "phpstan/phpstan-phpunit": "^0.12.10", + "psr/simple-cache": "^1.0", + "sebastian/diff": "^3.0|^4.0", + "symfony/cache": "^4.4.8|^5.0.6", + "symfony/console": "^4.4.8|^5.0.6", + "symfony/dependency-injection": "^4.4.8|^5.0.6", + "symfony/finder": "^4.4.8|^5.0.6", + "symfony/process": "^4.4.8|^5.0.6", + "symplify/auto-bind-parameter": "^8.1.2", + "symplify/autowire-array-parameter": "^8.1.2", + "symplify/console-color-diff": "^8.1.2", + "symplify/package-builder": "^8.1.2", + "symplify/parameter-name-guard": "^8.1.2", + "symplify/set-config-resolver": "^8.1.2", + "tracy/tracy": "^2.7" + }, + "replace": { + "rector/rector-prefixed": "self.version" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "johnkary/phpunit-speedtrap": "^3.2", + "ocramius/package-versions": "^1.4|^1.5", + "phpunit/phpunit": "^8.5|^9.0", + "psr/event-dispatcher": "^1.0", + "slam/phpstan-extensions": "^5.0", + "slevomat/coding-standard": "dev-master", + "symplify/changelog-linker": "^8.1.2", + "symplify/easy-coding-standard": "^8.1.2", + "symplify/easy-testing": "^8.1.2", + "symplify/monorepo-builder": "^8.1.2", + "symplify/phpstan-extensions": "^8.1.2", + "thecodingmachine/phpstan-strict-rules": "^0.12" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.8-dev" + } + }, + "autoload": { + "psr-4": { + "Rector\\Architecture\\": "rules/architecture/src", + "Rector\\PostRector\\": "packages/post-rector/src", + "Rector\\AttributeAwarePhpDoc\\": "packages/attribute-aware-php-doc/src", + "Rector\\Autodiscovery\\": "rules/autodiscovery/src", + "Rector\\BetterPhpDocParser\\": "packages/better-php-doc-parser/src", + "Rector\\CakePHP\\": "rules/cakephp/src", + "Rector\\Celebrity\\": "rules/celebrity/src", + "Rector\\ChangesReporting\\": "packages/changes-reporting/src", + "Rector\\CodeQuality\\": "rules/code-quality/src", + "Rector\\NodeRemoval\\": "packages/node-removal/src", + "Rector\\Reporting\\": "packages/reporting/src", + "Rector\\CodingStyle\\": "rules/coding-style/src", + "Rector\\ConsoleDiffer\\": "packages/console-differ/src", + "Rector\\Core\\": "src", + "Rector\\DeadCode\\": "rules/dead-code/src", + "Rector\\DocumentationGenerator\\": "packages/documentation-generator/src", + "Rector\\DoctrineCodeQuality\\": "rules/doctrine-code-quality/src", + "Rector\\DoctrineGedmoToKnplabs\\": "rules/doctrine-gedmo-to-knplabs/src", + "Rector\\Doctrine\\": "rules/doctrine/src", + "Rector\\DynamicTypeAnalysis\\": "packages/dynamic-type-analysis/src", + "Rector\\DoctrineAnnotationGenerated\\": "packages/doctrine-annotation-generated/src", + "Rector\\FileSystemRector\\": "packages/file-system-rector/src", + "Rector\\FrameworkMigration\\": "rules/framework-migration/src", + "Rector\\FamilyTree\\": "packages/family-tree/src", + "Rector\\Guzzle\\": "rules/guzzle/src", + "Rector\\JMS\\": "rules/jms/src", + "Rector\\Laravel\\": "rules/laravel/src", + "Rector\\Legacy\\": "rules/legacy/src", + "Rector\\MysqlToMysqli\\": "rules/mysql-to-mysqli/src", + "Rector\\NetteTesterToPHPUnit\\": "rules/nette-tester-to-phpunit/src", + "Rector\\NetteToSymfony\\": "rules/nette-to-symfony/src", + "Rector\\Nette\\": "rules/nette/src", + "Rector\\NodeCollector\\": "packages/node-collector/src", + "Rector\\NodeNameResolver\\": "packages/node-name-resolver/src", + "Rector\\NodeTypeResolver\\": "packages/node-type-resolver/src", + "Rector\\PhpAttribute\\": "packages/php-attribute/src", + "Rector\\PHPStanStaticTypeMapper\\": "packages/phpstan-static-type-mapper/src", + "Rector\\PHPStan\\": "rules/phpstan/src", + "Rector\\PHPUnitSymfony\\": "rules/phpunit-symfony/src", + "Rector\\Caching\\": "packages/caching/src", + "Rector\\PHPUnit\\": "rules/phpunit/src", + "Rector\\PSR4\\": "rules/psr4/src", + "Rector\\Phalcon\\": "rules/phalcon/src", + "Rector\\Php52\\": "rules/php52/src", + "Rector\\Php53\\": "rules/php53/src", + "Rector\\Php54\\": "rules/php54/src", + "Rector\\Php55\\": "rules/php55/src", + "Rector\\Php56\\": "rules/php56/src", + "Rector\\Php70\\": "rules/php70/src", + "Rector\\Php\\": "rules/php/src", + "Rector\\Php71\\": "rules/php71/src", + "Rector\\Php72\\": "rules/php72/src", + "Rector\\Php73\\": "rules/php73/src", + "Rector\\Php74\\": "rules/php74/src", + "Rector\\Php80\\": "rules/php80/src", + "Rector\\PHPOffice\\": "rules/php-office/src", + "Rector\\PhpDeglobalize\\": "rules/php-deglobalize/src", + "Rector\\PhpSpecToPHPUnit\\": "rules/php-spec-to-phpunit/src", + "Rector\\Polyfill\\": "packages/polyfill/src", + "Rector\\Privatization\\": "rules/privatization/src", + "Rector\\RectorGenerator\\": "packages/rector-generator/src", + "Rector\\RemovingStatic\\": "rules/removing-static/src", + "Rector\\Renaming\\": "rules/renaming/src", + "Rector\\Restoration\\": "rules/restoration/src", + "Rector\\SOLID\\": "rules/solid/src", + "Rector\\NodeNestingScope\\": "packages/node-nesting-scope/src", + "Rector\\Sensio\\": "rules/sensio/src", + "Rector\\StaticTypeMapper\\": "packages/static-type-mapper/src", + "Rector\\StrictCodeQuality\\": "rules/strict-code-quality/src", + "Rector\\SymfonyCodeQuality\\": "rules/symfony-code-quality/src", + "Rector\\SymfonyPHPUnit\\": "rules/symfony-phpunit/src", + "Rector\\Symfony\\": "rules/symfony/src", + "Rector\\Twig\\": "rules/twig/src", + "Rector\\TypeDeclaration\\": "rules/type-declaration/src", + "Rector\\VendorLocker\\": "packages/vendor-locker/src", + "Rector\\Performance\\": "rules/performance/src", + "Rector\\Naming\\": "rules/naming/src", + "Rector\\Order\\": "rules/order/src", + "Rector\\MockistaToMockery\\": "rules/mockista-to-mockery/src", + "Rector\\NetteKdyby\\": "rules/nette-kdyby/src", + "Rector\\NetteUtilsCodeQuality\\": "rules/nette-utils-code-quality/src", + "Rector\\NetteCodeQuality\\": "rules/nette-code-quality/src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tomas Votruba", + "email": "tomas.vot@gmail.com", + "homepage": "https://tomasvotruba.com" + }, + { + "name": "Jan Mikes", + "email": "j.mikes@me.com", + "homepage": "https://janmikes.cz" + } + ], + "description": "Instant upgrade and refactoring of your PHP code", + "homepage": "https://getrector.org", + "keywords": [ + "ast", + "automated refactoring", + "instant refactoring", + "instant upgrades" + ], + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2020-06-25T23:51:13+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-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/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "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": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-07-12T15:12:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "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": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2019-02-04T06:01:07+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-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" + ], + "time": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-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": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2019-09-14T09:02:43+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "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": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-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/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-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/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-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", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "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": "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", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.5.5", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "73e2e7f57d958e7228fce50dc0c61f58f017f9f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/73e2e7f57d958e7228fce50dc0c61f58f017f9f6", + "reference": "73e2e7f57d958e7228fce50dc0c61f58f017f9f6", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2020-04-17T01:09:41+00:00" + }, + { + "name": "symfony/cache", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "787eb05e137ad74fa5e51857b9884719760c7b2f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/787eb05e137ad74fa5e51857b9884719760c7b2f", + "reference": "787eb05e137ad74fa5e51857b9884719760c7b2f", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/cache": "~1.0", + "psr/log": "~1.0", + "symfony/cache-contracts": "^1.1.7|^2", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0" + }, + "conflict": { + "doctrine/dbal": "<2.5", + "symfony/dependency-injection": "<4.4", + "symfony/http-kernel": "<4.4", + "symfony/var-dumper": "<4.4" + }, + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0", + "symfony/cache-implementation": "1.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.5|^3.0", + "predis/predis": "^1.1", + "psr/simple-cache": "^1.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "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": "Symfony Cache component with PSR-6, PSR-16, and tags", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "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": "2020-06-09T14:15:34+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "87c92f62c494626598e9148208aaa6d1716b8e3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/87c92f62c494626598e9148208aaa6d1716b8e3c", + "reference": "87c92f62c494626598e9148208aaa6d1716b8e3c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/cache": "^1.0" + }, + "suggest": { + "symfony/cache-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "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": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/config", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "b8623ef3d99fe62a34baf7a111b576216965f880" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/b8623ef3d99fe62a34baf7a111b576216965f880", + "reference": "b8623ef3d99fe62a34baf7a111b576216965f880", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/filesystem": "^4.4|^5.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "symfony/finder": "<4.4" + }, + "require-dev": { + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/messenger": "^4.4|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/yaml": "^4.4|^5.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "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": "2020-05-23T13:08:13+00:00" + }, + { + "name": "symfony/console", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "34ac555a3627e324b660e318daa07572e1140123" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/34ac555a3627e324b660e318daa07572e1140123", + "reference": "34ac555a3627e324b660e318daa07572e1140123", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1|^2", + "symfony/string": "^5.1" + }, + "conflict": { + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/lock": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "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": "2020-06-15T12:59:21+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "6508423eded583fc07e88a0172803e1a62f0310c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6508423eded583fc07e88a0172803e1a62f0310c", + "reference": "6508423eded583fc07e88a0172803e1a62f0310c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.0", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1.6|^2" + }, + "conflict": { + "symfony/config": "<5.1", + "symfony/finder": "<4.4", + "symfony/proxy-manager-bridge": "<4.4", + "symfony/yaml": "<4.4" + }, + "provide": { + "psr/container-implementation": "1.0", + "symfony/service-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "^5.1", + "symfony/expression-language": "^4.4|^5.0", + "symfony/yaml": "^4.4|^5.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "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": "2020-06-12T08:11:32+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337", + "reference": "dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "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": "2020-05-27T08:34:37+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "7d0b927b9d3dc41d7d46cda38cbfcd20cdcbb896" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/7d0b927b9d3dc41d7d46cda38cbfcd20cdcbb896", + "reference": "7d0b927b9d3dc41d7d46cda38cbfcd20cdcbb896", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "^1.0", + "symfony/polyfill-php80": "^1.15", + "symfony/var-dumper": "^4.4|^5.0" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.1", + "symfony/http-kernel": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "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": "Symfony ErrorHandler Component", + "homepage": "https://symfony.com", + "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": "2020-05-30T20:35:19+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "cc0d059e2e997e79ca34125a52f3e33de4424ac7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/cc0d059e2e997e79ca34125a52f3e33de4424ac7", + "reference": "cc0d059e2e997e79ca34125a52f3e33de4424ac7", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/event-dispatcher-contracts": "^2", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "symfony/dependency-injection": "<4.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^4.4|^5.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "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": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "405952c4e90941a17e52ef7489a2bd94870bb290" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/405952c4e90941a17e52ef7489a2bd94870bb290", + "reference": "405952c4e90941a17e52ef7489a2bd94870bb290", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "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": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "6e4320f06d5f2cce0d96530162491f4465179157" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/6e4320f06d5f2cce0d96530162491f4465179157", + "reference": "6e4320f06d5f2cce0d96530162491f4465179157", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "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": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "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": "2020-05-30T20:35:19+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "4298870062bfc667cb78d2b379be4bf5dec5f187" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/4298870062bfc667cb78d2b379be4bf5dec5f187", + "reference": "4298870062bfc667cb78d2b379be4bf5dec5f187", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "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": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "f93055171b847915225bd5b0a5792888419d8d75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f93055171b847915225bd5b0a5792888419d8d75", + "reference": "f93055171b847915225bd5b0a5792888419d8d75", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php80": "^1.15" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/mime": "^4.4|^5.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "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": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com", + "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": "2020-06-15T06:52:54+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "a18c27ace1ef344ffcb129a5b089bad7643b387a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a18c27ace1ef344ffcb129a5b089bad7643b387a", + "reference": "a18c27ace1ef344ffcb129a5b089bad7643b387a", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "~1.0", + "symfony/deprecation-contracts": "^2.1", + "symfony/error-handler": "^4.4|^5.0", + "symfony/event-dispatcher": "^5.0", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "symfony/browser-kit": "<4.4", + "symfony/cache": "<5.0", + "symfony/config": "<5.0", + "symfony/console": "<4.4", + "symfony/dependency-injection": "<4.4", + "symfony/doctrine-bridge": "<5.0", + "symfony/form": "<5.0", + "symfony/http-client": "<5.0", + "symfony/mailer": "<5.0", + "symfony/messenger": "<5.0", + "symfony/translation": "<5.0", + "symfony/twig-bridge": "<5.0", + "symfony/validator": "<5.0", + "twig/twig": "<2.4" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/cache": "~1.0", + "symfony/browser-kit": "^4.4|^5.0", + "symfony/config": "^5.0", + "symfony/console": "^4.4|^5.0", + "symfony/css-selector": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/dom-crawler": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "symfony/routing": "^4.4|^5.0", + "symfony/stopwatch": "^4.4|^5.0", + "symfony/translation": "^4.4|^5.0", + "symfony/translation-contracts": "^1.1|^2", + "twig/twig": "^2.4|^3.0" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "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": "Symfony HttpKernel Component", + "homepage": "https://symfony.com", + "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": "2020-06-15T13:51:38+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "663f5dd5e14057d1954fe721f9709d35837f2447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/663f5dd5e14057d1954fe721f9709d35837f2447", + "reference": "663f5dd5e14057d1954fe721f9709d35837f2447", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "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": "2020-05-23T13:08:13+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.17.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d", + "reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "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" + ], + "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": "2020-06-06T08:46:27+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.17.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "6e4dbcf5e81eba86e36731f94fe56b1726835846" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/6e4dbcf5e81eba86e36731f94fe56b1726835846", + "reference": "6e4dbcf5e81eba86e36731f94fe56b1726835846", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "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": "2020-06-06T08:46:27+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.17.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "40309d1700e8f72447bb9e7b54af756eeea35620" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/40309d1700e8f72447bb9e7b54af756eeea35620", + "reference": "40309d1700e8f72447bb9e7b54af756eeea35620", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "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": "2020-06-14T14:40:37+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.17.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "7110338d81ce1cbc3e273136e4574663627037a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7110338d81ce1cbc3e273136e4574663627037a7", + "reference": "7110338d81ce1cbc3e273136e4574663627037a7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "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": "2020-06-06T08:46:27+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.17.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "471b096aede7025bace8eb356b9ac801aaba7e2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/471b096aede7025bace8eb356b9ac801aaba7e2d", + "reference": "471b096aede7025bace8eb356b9ac801aaba7e2d", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "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": "2020-06-06T08:46:27+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "f048e612a3905f34931127360bdd2def19a5e582" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582", + "reference": "f048e612a3905f34931127360bdd2def19a5e582", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "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": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.17.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "fa0837fe02d617d31fbb25f990655861bb27bd1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fa0837fe02d617d31fbb25f990655861bb27bd1a", + "reference": "fa0837fe02d617d31fbb25f990655861bb27bd1a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "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": "2020-06-06T08:46:27+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.17.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "4a5b6bba3259902e386eb80dd1956181ee90b5b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4a5b6bba3259902e386eb80dd1956181ee90b5b2", + "reference": "4a5b6bba3259902e386eb80dd1956181ee90b5b2", + "shasum": "" + }, + "require": { + "php": ">=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "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": "2020-06-06T08:46:27+00:00" + }, + { + "name": "symfony/process", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "7f6378c1fa2147eeb1b4c385856ce9de0d46ebd1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/7f6378c1fa2147eeb1b4c385856ce9de0d46ebd1", + "reference": "7f6378c1fa2147eeb1b4c385856ce9de0d46ebd1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "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": "2020-05-30T20:35:19+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "66a8f0957a3ca54e4f724e49028ab19d75a8918b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/66a8f0957a3ca54e4f724e49028ab19d75a8918b", + "reference": "66a8f0957a3ca54e4f724e49028ab19d75a8918b", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "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": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "0f7c58cf81dbb5dd67d423a89d577524a2ec0323" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/0f7c58cf81dbb5dd67d423a89d577524a2ec0323", + "reference": "0f7c58cf81dbb5dd67d423a89d577524a2ec0323", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/service-contracts": "^1.0|^2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" }, { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-20T17:43:50+00:00" + }, + { + "name": "symfony/string", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "ac70459db781108db7c6d8981dd31ce0e29e3298" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/ac70459db781108db7c6d8981dd31ce0e29e3298", + "reference": "ac70459db781108db7c6d8981dd31ce0e29e3298", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "~1.15" + }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0", + "symfony/http-client": "^4.4|^5.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "files": [ + "Resources/functions.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Volker Dusch", - "email": "github@wallbash.com" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony String component", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "url": "https://github.com/fabpot", + "type": "github" }, { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "time": "2020-06-11T12:16:36+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "46a942903059b0b05e601f00eb64179e05578c0f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/46a942903059b0b05e601f00eb64179e05578c0f", + "reference": "46a942903059b0b05e601f00eb64179e05578c0f", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<4.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "twig/twig": "^2.4|^3.0" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "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": "2020-05-30T20:35:19+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "eabaabfe1485ca955c5b53307eade15ccda57a15" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/eabaabfe1485ca955c5b53307eade15ccda57a15", + "reference": "eabaabfe1485ca955c5b53307eade15ccda57a15", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15" + }, + "require-dev": { + "symfony/var-dumper": "^4.4.9|^5.0.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code", + "homepage": "https://symfony.com", "keywords": [ + "clone", + "construct", "export", - "exporter" + "hydrate", + "instantiate", + "serialize" ], - "time": "2019-09-14T09:02:43+00:00" + "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": "2020-06-07T15:42:22+00:00" }, { - "name": "sebastian/global-state", - "version": "2.0.0", + "name": "symfony/yaml", + "version": "v5.1.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "url": "https://github.com/symfony/yaml.git", + "reference": "ea342353a3ef4f453809acc4ebc55382231d4d23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ea342353a3ef4f453809acc4ebc55382231d4d23", + "reference": "ea342353a3ef4f453809acc4ebc55382231d4d23", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<4.4" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "symfony/console": "^4.4|^5.0" }, "suggest": { - "ext-uopz": "*" + "symfony/console": "For validating YAML files using the lint command" }, + "bin": [ + "Resources/bin/yaml-lint" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "5.1-dev" } }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "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": "2017-04-27T15:39:26+00:00" + "time": "2020-05-20T17:43:50+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "3.0.3", + "name": "symplify/auto-bind-parameter", + "version": "v8.1.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + "url": "https://github.com/symplify/auto-bind-parameter.git", + "reference": "cc5777ca7dfdfdf3e7cd7c172cc3489013eb78f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "url": "https://api.github.com/repos/symplify/auto-bind-parameter/zipball/cc5777ca7dfdfdf3e7cd7c172cc3489013eb78f6", + "reference": "cc5777ca7dfdfdf3e7cd7c172cc3489013eb78f6", + "shasum": "" + }, + "require": { + "nette/utils": "^3.0", + "php": "^7.2", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5|^9.0", + "symplify/package-builder": "^8.1.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symplify\\AutoBindParameter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Auto bind parameters for your Symfony applications", + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2020-06-25T17:01:55+00:00" + }, + { + "name": "symplify/autowire-array-parameter", + "version": "v8.1.2", + "source": { + "type": "git", + "url": "https://github.com/symplify/autowire-array-parameter.git", + "reference": "53ca25892816621187fb1b178e19037bdcd527d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/autowire-array-parameter/zipball/53ca25892816621187fb1b178e19037bdcd527d2", + "reference": "53ca25892816621187fb1b178e19037bdcd527d2", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "nette/utils": "^3.0", + "php": "^7.2", + "symfony/dependency-injection": "^4.4|^5.0", + "symplify/package-builder": "^8.1.2" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^8.5|^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "8.2-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Symplify\\AutowireArrayParameter\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ + "description": "Autowire array parameters for your Symfony applications", + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "url": "https://github.com/tomasvotruba", + "type": "github" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" + "time": "2020-06-25T17:01:55+00:00" }, { - "name": "sebastian/object-reflector", - "version": "1.1.1", + "name": "symplify/console-color-diff", + "version": "v8.1.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" + "url": "https://github.com/symplify/console-color-diff.git", + "reference": "ce182246bb9c0ecc8517ba7055a90329d54c2e6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", + "url": "https://api.github.com/repos/symplify/console-color-diff/zipball/ce182246bb9c0ecc8517ba7055a90329d54c2e6c", + "reference": "ce182246bb9c0ecc8517ba7055a90329d54c2e6c", "shasum": "" }, "require": { - "php": "^7.0" + "nette/utils": "^3.0", + "php": "^7.2", + "sebastian/diff": "^3.0|^4.0", + "symfony/console": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0", + "symplify/package-builder": "^8.1.2" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^8.5|^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "8.2-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Symplify\\ConsoleColorDiff\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ + "description": "Package to print diffs in console with colors", + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "url": "https://github.com/tomasvotruba", + "type": "github" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" + "time": "2020-06-25T17:01:55+00:00" }, { - "name": "sebastian/recursion-context", - "version": "3.0.0", + "name": "symplify/package-builder", + "version": "v8.1.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + "url": "https://github.com/symplify/package-builder.git", + "reference": "91a5a58fc2e871ca84f49bb3a1b5a865723abd09" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "url": "https://api.github.com/repos/symplify/package-builder/zipball/91a5a58fc2e871ca84f49bb3a1b5a865723abd09", + "reference": "91a5a58fc2e871ca84f49bb3a1b5a865723abd09", "shasum": "" }, "require": { - "php": "^7.0" + "nette/finder": "^2.5", + "nette/utils": "^3.0", + "php": "^7.2", + "symfony/config": "^4.4|^5.0", + "symfony/console": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0", + "symfony/yaml": "^4.4|^5.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^8.5|^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "8.2-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Symplify\\PackageBuilder\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, + "description": "Dependency Injection, Console and Kernel toolkit for Symplify packages.", + "funding": [ { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "url": "https://github.com/tomasvotruba", + "type": "github" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" + "time": "2020-06-25T16:39:17+00:00" }, { - "name": "sebastian/resource-operations", - "version": "1.0.0", + "name": "symplify/parameter-name-guard", + "version": "v8.1.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + "url": "https://github.com/symplify/parameter-name-guard.git", + "reference": "17189fb5e57300df0a540ff28925fcaf043b0e82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "url": "https://api.github.com/repos/symplify/parameter-name-guard/zipball/17189fb5e57300df0a540ff28925fcaf043b0e82", + "reference": "17189fb5e57300df0a540ff28925fcaf043b0e82", "shasum": "" }, "require": { - "php": ">=5.6.0" + "nette/utils": "^3.0", + "php": "^7.2", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0" }, - "type": "library", + "require-dev": { + "phpunit/phpunit": "^8.5|^9.0" + }, + "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "8.2-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Symplify\\ParameterNameGuard\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ + "description": "Prevent silent parameter typos that silently break your app", + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "url": "https://github.com/tomasvotruba", + "type": "github" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "time": "2020-06-25T16:39:17+00:00" }, { - "name": "sebastian/version", - "version": "2.0.1", + "name": "symplify/set-config-resolver", + "version": "v8.1.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + "url": "https://github.com/symplify/set-config-resolver.git", + "reference": "39fe044760e6af838053acf862e707abbf8fe751" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "url": "https://api.github.com/repos/symplify/set-config-resolver/zipball/39fe044760e6af838053acf862e707abbf8fe751", + "reference": "39fe044760e6af838053acf862e707abbf8fe751", "shasum": "" }, "require": { - "php": ">=5.6" + "nette/utils": "^3.0", + "php": "^7.2", + "symfony/console": "^4.4|^5.0", + "symfony/filesystem": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symplify/smart-file-system": "^8.1.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5|^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "8.2-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Symplify\\SetConfigResolver\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ + "description": "Resolve config and sets from configs and cli opptions for CLI applications", + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "url": "https://github.com/tomasvotruba", + "type": "github" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" + "time": "2020-06-25T17:01:55+00:00" }, { - "name": "squizlabs/php_codesniffer", - "version": "3.5.5", + "name": "symplify/smart-file-system", + "version": "v8.1.2", "source": { "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "73e2e7f57d958e7228fce50dc0c61f58f017f9f6" + "url": "https://github.com/symplify/smart-file-system.git", + "reference": "962b7003f10a4ddbc200db2b1148f5ca3b90219d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/73e2e7f57d958e7228fce50dc0c61f58f017f9f6", - "reference": "73e2e7f57d958e7228fce50dc0c61f58f017f9f6", + "url": "https://api.github.com/repos/symplify/smart-file-system/zipball/962b7003f10a4ddbc200db2b1148f5ca3b90219d", + "reference": "962b7003f10a4ddbc200db2b1148f5ca3b90219d", "shasum": "" }, "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" + "nette/utils": "^3.0", + "php": "^7.2", + "symfony/filesystem": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "nette/finder": "^2.5", + "phpunit/phpunit": "^8.5|^9.0" }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "3.x-dev" + "dev-master": "8.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symplify\\SmartFileSystem\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ + "description": "Sanitized FileInfo with safe getRealPath() and other handy methods", + "funding": [ { - "name": "Greg Sherwood", - "role": "lead" + "url": "https://github.com/tomasvotruba", + "type": "github" } ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "time": "2020-04-17T01:09:41+00:00" + "time": "2020-06-25T16:39:17+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.17.1", + "name": "thecodingmachine/phpstan-strict-rules", + "version": "v0.12.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d" + "url": "https://github.com/thecodingmachine/phpstan-strict-rules.git", + "reference": "8c58cc87dc870382b228c95c4f1cc9fc871aaf28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d", - "reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d", + "url": "https://api.github.com/repos/thecodingmachine/phpstan-strict-rules/zipball/8c58cc87dc870382b228c95c4f1cc9fc871aaf28", + "reference": "8c58cc87dc870382b228c95c4f1cc9fc871aaf28", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.1", + "phpstan/phpstan": "^0.12" }, - "suggest": { - "ext-ctype": "For best performance" + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^7.1" }, - "type": "library", + "type": "phpstan-extension", "extra": { "branch-alias": { - "dev-master": "1.17-dev" + "dev-master": "0.12-dev" }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "phpstan": { + "includes": [ + "phpstan-strict-rules.neon" + ] } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] + "TheCodingMachine\\PHPStan\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1557,37 +5824,12 @@ ], "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" - ], - "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" + "name": "David Négrier", + "email": "d.negrier@thecodingmachine.com" } ], - "time": "2020-06-06T08:46:27+00:00" + "description": "A set of additional rules for PHPStan based on best practices followed at TheCodingMachine", + "time": "2019-12-04T11:25:22+00:00" }, { "name": "theseer/tokenizer", @@ -1629,6 +5871,79 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "time": "2019-06-13T22:48:21+00:00" }, + { + "name": "tracy/tracy", + "version": "v2.7.5", + "source": { + "type": "git", + "url": "https://github.com/nette/tracy.git", + "reference": "95b1c6e35d61df8ef91a4633ba3cf835d2d47e5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tracy/zipball/95b1c6e35d61df8ef91a4633ba3cf835d2d47e5e", + "reference": "95b1c6e35d61df8ef91a4633ba3cf835d2d47e5e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-session": "*", + "php": ">=7.1" + }, + "conflict": { + "nette/di": "<3.0" + }, + "require-dev": { + "latte/latte": "^2.5", + "nette/di": "^3.0", + "nette/mail": "^3.0", + "nette/tester": "^2.2", + "nette/utils": "^3.0", + "phpstan/phpstan": "^0.12", + "psr/log": "^1.0" + }, + "suggest": { + "https://nette.org/donate": "Please support Tracy via a donation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "classmap": [ + "src" + ], + "files": [ + "src/Tracy/shortcuts.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI support. You will love it.", + "homepage": "https://tracy.nette.org", + "keywords": [ + "Xdebug", + "debug", + "debugger", + "nette", + "profiler" + ], + "time": "2020-05-17T09:50:45+00:00" + }, { "name": "webmozart/assert", "version": "1.9.0", diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..b70093f --- /dev/null +++ b/docs/index.md @@ -0,0 +1,54 @@ +# DOCUMENTATION + +Reader example: + +```php +// Initialize reader +$reader = \SPSS\Reader::fromFile('path/to/file.sav'); + +// Read header data +$reader->readHeader(); +// var_dump($reader->header); + +// Read full data +$reader->read(); +// var_dump($reader->variables); +// var_dump($reader->valueLabels); +// var_dump($reader->documents); +// var_dump($reader->data); +``` +or +```php +$reader = \SPSS\Reader::fromString(file_get_contents('path/to/file.sav'))->read(); +``` + +Writer example: + +```php +$writer = new \SPSS\Writer([ + 'header' => [ + 'prodName' => '@(#) SPSS DATA FILE test', + 'layoutCode' => 2, + 'compression' => 1, + 'weightIndex' => 0, + 'bias' => 100, + 'creationDate' => '01 Feb 01', + 'creationTime' => '01:01:01', + ], + 'variables' => [ + [ + 'name' => 'VAR1', # For UTF-8, 64 / 3 = 21, mb_substr($var1, 0, 21); + 'width' => 0, + 'decimals' => 0 + 'format' => 5, + 'columns' => 50, + 'align' => 1, + 'measure' => 1, + 'data' => [ + 1, 2, 3 + ], + ], + ... + ] +]); +``` diff --git a/examples/data.sav b/examples/data.sav index b1f5ea8..ad2c501 100644 Binary files a/examples/data.sav and b/examples/data.sav differ diff --git a/examples/read.php b/examples/read.php index b965cc5..8991e1d 100644 --- a/examples/read.php +++ b/examples/read.php @@ -2,10 +2,10 @@ require __DIR__ . '/../vendor/autoload.php'; -$files = [ +$files = array( // __DIR__ . '/test2.sav', __DIR__ . '/data.sav', -]; +); function __header($str, $char = '#') { diff --git a/examples/readCases.php b/examples/readCases.php new file mode 100644 index 0000000..ad202e6 --- /dev/null +++ b/examples/readCases.php @@ -0,0 +1,66 @@ +readMetaData(); + + echo PHP_EOL; + + echo __header(sprintf('OPEN FILE %s', $file)); + + echo __title('Header'); + echo __content($reader->header); + + echo __title('Documents'); + echo __content($reader->documents); + + echo __title('Variables'); + echo __content($reader->variables); + + echo __title('Values-labels'); + echo __content($reader->valueLabels); + + echo __title('Additional-info'); + echo __content($reader->info); + + while ($reader->readCase()) { + echo __title('Case ' . $reader->getCaseNumber()); + echo __content($reader->getCase()); + } + echo PHP_EOL; +} diff --git a/examples/write.php b/examples/write.php index 9378af9..03f5b0e 100644 --- a/examples/write.php +++ b/examples/write.php @@ -6,8 +6,8 @@ $file = __DIR__ . '/data.sav'; -$writer = new \SPSS\Sav\Writer([ - 'header' => [ +$writer = new \SPSS\Sav\Writer(array( + 'header' => array( 'prodName' => '@(#) IBM SPSS STATISTICS 64-bit Macintosh 23.0.0.0', 'creationDate' => '05 Oct 18', 'creationTime' => '01:36:53', @@ -16,7 +16,7 @@ // 'compression' => 1, // 'bias' => 100, // 'fileLabel' => '', - ], + ), // 'info' => [ // 'machineInteger' => [ // 'machineCode' => 720, @@ -28,46 +28,46 @@ // 'lowest' => -1.7976931348623155e+308, // ], // ], - 'variables' => [ - [ + 'variables' => array( + array( 'name' => 'aaa', 'format' => Variable::FORMAT_TYPE_F, 'width' => 4, 'decimals' => 2, 'label' => 'test', - 'values' => [ + 'values' => array( 222 => 'foo', '13.22' => 'bar', - ], + ), // 'missing' => [], 'columns' => 16, 'alignment' => Variable::ALIGN_RIGHT, 'measure' => Variable::MEASURE_SCALE, - 'attributes' => [ + 'attributes' => array( '$@Role' => Variable::ROLE_PARTITION, - ], - 'data' => [1, 1, 1], - ], - [ + ), + 'data' => array(1, 1, 1), + ), + array( 'name' => 'bbbb_bbbbbb12', 'format' => Variable::FORMAT_TYPE_A, 'width' => 28, // 'decimals' => 0, 'label' => 'test', - 'values' => [ + 'values' => array( 'm' => 'male', 'f' => 'female', - ], + ), // 'missing' => [], 'columns' => 8, 'alignment' => Variable::ALIGN_LEFT, 'measure' => Variable::MEASURE_NOMINAL, - 'attributes' => [ + 'attributes' => array( '$@Role' => Variable::ROLE_SPLIT, - ], - 'data' => ['foo', 'bar', 'baz'], - ], - [ + ), + 'data' => array('foo', 'bar', 'baz'), + ), + array( 'name' => 'BBBB_BBBBBB13', 'format' => Variable::FORMAT_TYPE_COMMA, 'width' => 8, @@ -80,13 +80,13 @@ 'columns' => 8, 'alignment' => Variable::ALIGN_RIGHT, 'measure' => Variable::MEASURE_NOMINAL, - 'attributes' => [ + 'attributes' => array( '$@Role' => Variable::ROLE_INPUT, - ], - 'data' => [1, 1, 1], - ], - ], - ] + ), + 'data' => array(1, 1, 1), + ), + ), + ) ); $writer->save($file); diff --git a/examples/write12.php b/examples/write12.php index 58acd1a..5dbe404 100644 --- a/examples/write12.php +++ b/examples/write12.php @@ -1,34 +1,33 @@ [ +$writer = new \SPSS\Sav\Writer(array( + 'header' => array( 'prodName' => '@(#) IBM SPSS STATISTICS', 'layoutCode' => 2, 'creationDate' => date('d M y'), 'creationTime' => date('H:i:s'), - ], - 'variables' => [ - [ + ), + 'variables' => array( + array( 'name' => 'aaa', 'width' => 16, 'format' => 1, - ], - [ + ), + array( 'name' => 'ccc', 'format' => 5, - 'values' => [ + 'values' => array( 1 => 'Panel', - ], - ], - ], -]); + ), + ), + ), +)); $writer->save($file); diff --git a/examples/writeCases.php b/examples/writeCases.php new file mode 100644 index 0000000..db47d67 --- /dev/null +++ b/examples/writeCases.php @@ -0,0 +1,100 @@ + array( + 'prodName' => '@(#) IBM SPSS STATISTICS 64-bit Macintosh 23.0.0.0', + 'creationDate' => '05 Oct 18', + 'creationTime' => '01:36:53', + 'weightIndex' => 0, + // 'casesCount' => 3, + // 'compression' => 1, + // 'bias' => 100, + // 'fileLabel' => '', + ), + // 'info' => [ + // 'machineInteger' => [ + // 'machineCode' => 720, + // 'version' => [23, 0, 0], + // ], + // 'machineFloatingPoint' => [ + // 'sysmis' => -1.7976931348623157e+308, + // 'highest' => 1.7976931348623157e+308, + // 'lowest' => -1.7976931348623155e+308, + // ], + // ], + 'variables' => array( + array( + 'name' => 'aaa', + 'format' => Variable::FORMAT_TYPE_F, + 'width' => 4, + 'decimals' => 2, + 'label' => 'test', + 'values' => array( + 222 => 'foo', + '13.22' => 'bar', + ), + // 'missing' => [], + 'columns' => 16, + 'alignment' => Variable::ALIGN_RIGHT, + 'measure' => Variable::MEASURE_SCALE, + 'attributes' => array( + '$@Role' => Variable::ROLE_PARTITION, + ), + ), + array( + 'name' => 'bbbb_bbbbbb12', + 'format' => Variable::FORMAT_TYPE_A, + 'width' => 28, + // 'decimals' => 0, + 'label' => 'test', + 'values' => array( + 'm' => 'male', + 'f' => 'female', + ), + // 'missing' => [], + 'columns' => 8, + 'alignment' => Variable::ALIGN_LEFT, + 'measure' => Variable::MEASURE_NOMINAL, + 'attributes' => array( + '$@Role' => Variable::ROLE_SPLIT, + ), + ), + array( + 'name' => 'BBBB_BBBBBB13', + 'format' => Variable::FORMAT_TYPE_COMMA, + 'width' => 8, + 'decimals' => 2, + // 'label' => 'test', + // 'values' => [ + // 1 => 'test' + // ], + // 'missing' => [], + 'columns' => 8, + 'alignment' => Variable::ALIGN_RIGHT, + 'measure' => Variable::MEASURE_NOMINAL, + 'attributes' => array( + '$@Role' => Variable::ROLE_INPUT, + ), + ), + ), + ) +); + +$data = array( + array(1, 'foo', 1), + array(1, 'bar', 1), + array(1, 'baz', 1), +); + +foreach ($data as $case => $row) { + $writer->writeCase($row); +} + +$writer->save($file); +$writer->close(); diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..92a52bf --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,13 @@ +includes: + - vendor/phpstan/phpstan-strict-rules/rules.neon + - vendor/ergebnis/phpstan-rules/rules.neon + - vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon + +parameters: + level: max + paths: + - src + + checkMissingIterableValueType: true + checkGenericClassInNonGenericObjectType: false + reportUnmatchedIgnoredErrors: true diff --git a/rector.yaml b/rector.yaml new file mode 100644 index 0000000..3cfeeb3 --- /dev/null +++ b/rector.yaml @@ -0,0 +1,18 @@ +# rector.yaml +parameters: + sets: + - 'action-injection-to-constructor-injection' + - 'array-str-functions-to-static-call' + - 'celebrity' + - 'doctrine' + - 'phpstan' + - 'phpunit-code-quality' + - 'solid' + - 'early-return' + - 'doctrine-code-quality' + - 'code-quality' + - 'php55' + - 'php56' + - 'php71' + - 'php72' + - 'php73' diff --git a/src/Buffer.php b/src/Buffer.php index 04380b7..5df3766 100644 --- a/src/Buffer.php +++ b/src/Buffer.php @@ -32,12 +32,12 @@ class Buffer /** * Buffer constructor. * - * @param resource $stream Stream resource to wrap. - * @param array $options Associative array of options. + * @param resource $stream stream resource to wrap + * @param array $options associative array of options */ - private function __construct($stream, $options = []) + private function __construct($stream, $options = array()) { - if (! is_resource($stream)) { + if (!\is_resource($stream)) { throw new \InvalidArgumentException('Stream must be a resource.'); } $this->_stream = $stream; @@ -52,18 +52,19 @@ private function __construct($stream, $options = []) * * @param resource|string $resource Entity body data * @param array $options Additional options + * * @return Buffer */ - public static function factory($resource = '', $options = []) + public static function factory($resource = '', $options = array()) { - $type = gettype($resource); + $type = \gettype($resource); switch ($type) { case 'string': $stream = isset($options['memory']) ? fopen('php://memory', 'rb+') : fopen('php://temp', 'rb+'); - if ($resource !== '') { + if ('' !== $resource) { fwrite($stream, $resource); fseek($stream, 0); } @@ -83,8 +84,10 @@ public static function factory($resource = '', $options = []) /** * @param int $length * @param bool $skip - * @return Buffer + * * @throws Exception + * + * @return Buffer */ public function allocate($length, $skip = true) { @@ -101,6 +104,7 @@ public function allocate($length, $skip = true) /** * @param int $length + * * @return void */ public function skip($length) @@ -110,6 +114,7 @@ public function skip($length) /** * @param string $file Path to file + * * @return false|int */ public function saveToFile($file) @@ -121,12 +126,13 @@ public function saveToFile($file) /** * @param resource $resource - * @param null|int $maxlength + * @param int|null $maxlength + * * @return false|int */ public function writeStream($resource, $maxlength = null) { - if (! is_resource($resource)) { + if (!\is_resource($resource)) { throw new \InvalidArgumentException('Invalid resource type.'); } @@ -153,6 +159,7 @@ public function getStream() * @param int $length * @param int $round * @param null $charset + * * @return false|string */ public function readString($length, $round = 0, $charset = null) @@ -176,12 +183,13 @@ public function readString($length, $round = 0, $charset = null) /** * @param $length + * * @return false|array */ public function readBytes($length) { $bytes = $this->read($length); - if ($bytes !== false) { + if (false !== $bytes) { return array_values(unpack('C*', $bytes)); } @@ -190,12 +198,13 @@ public function readBytes($length) /** * @param int $length + * * @return false|string */ public function read($length = null) { $bytes = stream_get_contents($this->_stream, $length, $this->_position); - if ($bytes !== false) { + if (false !== $bytes) { $this->_position += $length; } @@ -206,6 +215,7 @@ public function read($length = null) * @param $data * @param int|string $length * @param null $charset + * * @return false|int */ public function writeString($data, $length = '*', $charset = null) @@ -221,7 +231,8 @@ public function writeString($data, $length = '*', $charset = null) /** * @param string $data - * @param null|int $length + * @param int|null $length + * * @return false|int */ public function write($data, $length = null) @@ -233,7 +244,7 @@ public function write($data, $length = null) } /** - * @return double + * @return float */ public function readDouble() { @@ -242,6 +253,7 @@ public function readDouble() /** * @param $data + * * @return false|int */ public function writeDouble($data) @@ -253,6 +265,7 @@ public function writeDouble($data) * @param $data * @param $format * @param null $length + * * @return false|int */ public function writeNumeric($data, $format, $length = null) @@ -270,6 +283,7 @@ public function readFloat() /** * @param $data + * * @return false|int */ public function writeFloat($data) @@ -287,6 +301,7 @@ public function readInt() /** * @param $data + * * @return false|int */ public function writeInt($data) @@ -304,6 +319,7 @@ public function readShort() /** * @param $data + * * @return false|int */ public function writeShort($data) @@ -313,6 +329,7 @@ public function writeShort($data) /** * @param $length + * * @return false|int */ public function writeNull($length) @@ -332,6 +349,7 @@ public function position() /** * @param int $offset * @param int $whence + * * @return int */ public function seek($offset, $whence = SEEK_SET) @@ -360,6 +378,14 @@ public function truncate() $this->_position = 0; } + /** + * @return true|false + */ + public function close() + { + return fclose($this->_stream); + } + /** * @return array */ @@ -371,12 +397,13 @@ public function getMetaData() /** * @param int $length * @param string $format - * @return false|int|float|double + * + * @return false|int|float|float */ private function readNumeric($length, $format) { $bytes = $this->read($length); - if ($bytes !== false) { + if (false !== $bytes) { if ($this->isBigEndian) { $bytes = strrev($bytes); } diff --git a/src/Sav/Reader.php b/src/Sav/Reader.php index 5895c4a..6c7c562 100644 --- a/src/Sav/Reader.php +++ b/src/Sav/Reader.php @@ -5,8 +5,9 @@ use SPSS\Buffer; use SPSS\Sav\Record\Header; use SPSS\Sav\Record\Info; -use SPSS\Sav\Record\Variable; use SPSS\Sav\Record\ValueLabel; +use SPSS\Sav\Record\Variable; +use SPSS\Utils; class Reader { @@ -18,27 +19,37 @@ class Reader /** * @var Variable[] */ - public $variables = []; + public $variables = array(); /** * @var ValueLabel[] */ - public $valueLabels = []; + public $valueLabels = array(); /** * @var array */ - public $documents = []; + public $documents = array(); /** * @var Info[] */ - public $info = []; + public $info = array(); /** * @var array */ - public $data = []; + public $data = array(); + + /** + * @var int + */ + public $lastCase = -1; + + /** + * @var record + */ + public $record; /** * @var Buffer @@ -47,8 +58,6 @@ class Reader /** * Reader constructor. - * - * @param Buffer $buffer */ private function __construct(Buffer $buffer) { @@ -58,15 +67,17 @@ private function __construct(Buffer $buffer) /** * @param string $file + * * @return Reader */ public static function fromFile($file) { - return new self(Buffer::factory(fopen($file, 'rb'))); + return new self(Buffer::factory(fopen($file, 'r'))); } /** * @param string $str + * * @return Reader */ public static function fromString($str) @@ -75,7 +86,15 @@ public static function fromString($str) } /** - * @return $this + * @return self + */ + public function readMetaData() + { + return $this->readHeader()->readBody(); + } + + /** + * @return self */ public function read() { @@ -83,7 +102,7 @@ public function read() } /** - * @return $this + * @return self */ public function readHeader() { @@ -93,28 +112,33 @@ public function readHeader() } /** - * @return $this + * @return self */ public function readBody() { - if (! $this->header) { + if (!$this->header) { $this->readHeader(); } // TODO: refactory $infoCollection = new Record\InfoCollection(); + $tempVars = array(); + $posVar = 0; do { $recType = $this->_buffer->readInt(); switch ($recType) { case Record\Variable::TYPE: - $this->variables[] = Record\Variable::fill($this->_buffer); + $variable = Record\Variable::fill($this->_buffer); + $variable->realPosition = $posVar; + $tempVars[] = $variable; + ++$posVar; break; case Record\ValueLabel::TYPE: - $this->valueLabels[] = Record\ValueLabel::fill($this->_buffer, [ + $this->valueLabels[] = Record\ValueLabel::fill($this->_buffer, array( // TODO: refactory - 'variables' => $this->variables, - ]); + 'variables' => $tempVars, + )); break; case Record\Info::TYPE: $this->info = $infoCollection->fill($this->_buffer); @@ -123,13 +147,35 @@ public function readBody() $this->documents = Record\Document::fill($this->_buffer)->toArray(); break; } - } while ($recType !== Record\Data::TYPE); + } while (Record\Data::TYPE !== $recType); + + // Excluding the records that are creating only as a consequence of very long string records + // from the variables computation. + $veryLongStrings = array(); + if (isset($this->info[Record\Info\VeryLongString::SUBTYPE])) { + $veryLongStrings = $this->info[Record\Info\VeryLongString::SUBTYPE]->toArray(); + } + + $segmentsCount = 0; + foreach ($tempVars as $index => $var) { + // Skip blank records from the variables computation + if (-1 !== $var->width) { + if ($segmentsCount <= 0) { + $segmentsCount = Utils::widthToSegments( + isset($veryLongStrings[$var->name]) ? + $veryLongStrings[$var->name] : $var->width + ); + $this->variables[] = $var; + } + --$segmentsCount; + } + } return $this; } /** - * @return $this + * @return self */ public function readData() { @@ -137,4 +183,40 @@ public function readData() return $this; } + + /** + * @return bool + */ + public function readCase() + { + if (!isset($this->record)) { + $this->record = Record\Data::create(); + } + + ++$this->lastCase; + + if (($this->lastCase >= 0) && ($this->lastCase < $this->_buffer->context->header->casesCount)) { + $this->record->readCase($this->_buffer, $this->lastCase); + + return true; + } + + return false; + } + + /** + * @return int + */ + public function getCaseNumber() + { + return $this->lastCase; + } + + /** + * @return int + */ + public function getCase() + { + return $this->record->getRow(); + } } diff --git a/src/Sav/Record.php b/src/Sav/Record.php index f31c9f4..15877b7 100644 --- a/src/Sav/Record.php +++ b/src/Sav/Record.php @@ -11,7 +11,7 @@ abstract class Record implements RecordInterface * * @param array $data */ - public function __construct($data = []) + public function __construct($data = array()) { foreach ($data as $key => $value) { $this->{$key} = $value; @@ -19,11 +19,11 @@ public function __construct($data = []) } /** - * @param Buffer $buffer * @param array $data + * * @return static */ - public static function fill(Buffer $buffer, $data = []) + public static function fill(Buffer $buffer, $data = array()) { $record = new static($data); $record->read($buffer); @@ -31,11 +31,21 @@ public static function fill(Buffer $buffer, $data = []) return $record; } + /** + * @param array $data + * + * @return static + */ + public static function create($data = array()) + { + return new static($data); + } + /** * @return array */ public function toArray() { - return []; + return array(); } } diff --git a/src/Sav/Record/Data.php b/src/Sav/Record/Data.php index ec67d76..4565172 100644 --- a/src/Sav/Record/Data.php +++ b/src/Sav/Record/Data.php @@ -29,34 +29,115 @@ class Data extends Record /** * @var array [case_index][var_index] */ - public $matrix = []; + public $matrix = array(); + + /** + * @var array [var_index] + */ + public $row = array(); /** * @var array Latest opcodes data */ - private $opcodes = []; + protected $opcodes = array(); /** * @var int Current opcode index */ - private $opcodeIndex = 0; + protected $opcodeIndex = 0; + + /** + * @var int Position where the data start + */ + protected $startData = -1; + + /** + * @var Buffer Temporary buffer + */ + protected $dataBuffer; + + /** + * @param int $case + * + * @throws Exception + */ + public function readCase(Buffer $buffer, $case) + { + /* check if this is the first time */ + if (-1 === $this->startData) { + $this->opcodeIndex = 8; + $this->opcodes = array(); + + $this->startData = $buffer->position(); + if (0 !== $buffer->readInt()) { + throw new \InvalidArgumentException('Error reading data record. Non-zero value found.'); + } + if (!isset($buffer->context->variables)) { + throw new \InvalidArgumentException('Variables required'); + } + if (!isset($buffer->context->header)) { + throw new \InvalidArgumentException('Header required'); + } + if (!isset($buffer->context->info)) { + throw new \InvalidArgumentException('Info required'); + } + } + + $compressed = $buffer->context->header->compression; + $bias = $buffer->context->header->bias; + $casesCount = $buffer->context->header->casesCount; + + // @var Variable[] $variables + $variables = $buffer->context->variables; + + // @var Record\Info[] $info + $info = $buffer->context->info; + + $veryLongStrings = array(); + if (isset($info[Record\Info\VeryLongString::SUBTYPE])) { + $veryLongStrings = $info[Record\Info\VeryLongString::SUBTYPE]->toArray(); + } + + if (isset($info[Record\Info\MachineFloatingPoint::SUBTYPE])) { + $sysmis = $info[Record\Info\MachineFloatingPoint::SUBTYPE]->sysmis; + } else { + $sysmis = NAN; + } + + if (($case >= 0) && ($case < $casesCount)) { + $this->row = $this->readCaseData( + $buffer, + $compressed, + $bias, + $variables, + $veryLongStrings, + $sysmis + ); + } + } /** - * @param Buffer $buffer * @throws Exception */ public function read(Buffer $buffer) { - if ($buffer->readInt() !== 0) { + if (-1 === $this->startData) { + $this->startData = $buffer->position(); + } + + if (0 !== $buffer->readInt()) { throw new \InvalidArgumentException('Error reading data record. Non-zero value found.'); } - if (! isset($buffer->context->variables)) { + + if (!isset($buffer->context->variables)) { throw new \InvalidArgumentException('Variables required'); } - if (! isset($buffer->context->header)) { + + if (!isset($buffer->context->header)) { throw new \InvalidArgumentException('Header required'); } - if (! isset($buffer->context->info)) { + + if (!isset($buffer->context->info)) { throw new \InvalidArgumentException('Info required'); } @@ -70,7 +151,7 @@ public function read(Buffer $buffer) /** @var Record\Info[] $info */ $info = $buffer->context->info; - $veryLongStrings = []; + $veryLongStrings = array(); if (isset($info[Record\Info\VeryLongString::SUBTYPE])) { $veryLongStrings = $info[Record\Info\VeryLongString::SUBTYPE]->toArray(); } @@ -83,117 +164,79 @@ public function read(Buffer $buffer) $this->opcodeIndex = 8; - for ($case = 0; $case < $casesCount; $case++) { - $parent = -1; - $octs = 0; - foreach ($variables as $index => $var) { - - $isNumeric = $var->width === 0 && \SPSS\Sav\Variable::isNumberFormat($var->write[1]); - $width = isset($var->write[1]) ? $var->write[1] : $var->width; - - // var_dump($var); - // exit; - - if ($isNumeric) { - if (! $compressed) { - $this->matrix[$case][$index] = $buffer->readDouble(); - } else { - $opcode = $this->readOpcode($buffer); - switch ($opcode) { - case self::OPCODE_NOP; - break; - case self::OPCODE_EOF; - throw new Exception( - 'Error reading data: unexpected end of compressed data file (cluster code 252)' - ); - break; - case self::OPCODE_RAW_DATA; - $this->matrix[$case][$index] = $buffer->readDouble(); - break; - case self::OPCODE_SYSMISS; - $this->matrix[$case][$index] = $sysmis; - break; - default: - $this->matrix[$case][$index] = $opcode - $bias; - break; - } - } - } else { - $val = ''; - if (! $compressed) { - $val = $buffer->readString(8); - } else { - $opcode = $this->readOpcode($buffer); - switch ($opcode) { - case self::OPCODE_NOP; - break; - case self::OPCODE_EOF; - throw new Exception( - 'Error reading data: unexpected end of compressed data file (cluster code 252)' - ); - break; - case self::OPCODE_RAW_DATA; - $val = $buffer->readString(8); - break; - case self::OPCODE_WHITESPACES; - $val = ' '; - break; - } - } - - if ($parent >= 0) { - $this->matrix[$case][$parent] .= $val; - $octs--; - if ($octs <= 0) { - $this->matrix[$case][$parent] = rtrim($this->matrix[$case][$parent]); - $parent = -1; - } - } else { - $width = isset($veryLongStrings[$var->name]) ? $veryLongStrings[$var->name] : $width; - if ($width > 0) { - $octs = Utils::widthToOcts($width) - 1; // Buffer::roundUp($width, 8) / 8) -1; - if ($octs > 0) { - $parent = $index; - } else { - $val = rtrim($val); - } - $this->matrix[$case][$index] = $val; - } - } - } - } + for ($case = 0; $case < $casesCount; ++$case) { + $this->matrix[$case] = $this->readCaseData( + $buffer, + $compressed, + $bias, + $variables, + $veryLongStrings, + $sysmis + ); } } /** - * @param Buffer $buffer - * @return int + * @param array $row */ - public function readOpcode(Buffer $buffer) + public function writeCase(Buffer $buffer, $row) { - if ($this->opcodeIndex >= 8) { - $this->opcodes = $buffer->readBytes(8); - $this->opcodeIndex = 0; + if (!isset($buffer->context->variables)) { + throw new \InvalidArgumentException('Variables required'); } - return 0xFF & $this->opcodes[$this->opcodeIndex++]; + if (!isset($buffer->context->header)) { + throw new \InvalidArgumentException('Header required'); + } + + if (!isset($buffer->context->info)) { + throw new \InvalidArgumentException('Info required'); + } + + $compressed = $buffer->context->header->compression; + $bias = $buffer->context->header->bias; + $casesCount = $buffer->context->header->casesCount; + + /** @var Variable[] $variables */ + $variables = $buffer->context->variables; + + /** @var Record\Info[] $info */ + $info = $buffer->context->info; + + $veryLongStrings = array(); + if (isset($info[Record\Info\VeryLongString::SUBTYPE])) { + $veryLongStrings = $info[Record\Info\VeryLongString::SUBTYPE]->toArray(); + } + + if (isset($info[Record\Info\MachineFloatingPoint::SUBTYPE])) { + $sysmis = $info[Record\Info\MachineFloatingPoint::SUBTYPE]->sysmis; + } else { + $sysmis = NAN; + } + + if (!isset($this->dataBuffer)) { + $this->dataBuffer = Buffer::factory('', array('memory' => true)); + $buffer->writeInt(self::TYPE); + $this->startData = $buffer->position(); + $buffer->writeInt(0); + } + //for ($case = 0; $case < $casesCount; $case++) { + $this->writeCaseData($buffer, $row, $compressed, $bias, $variables, $veryLongStrings, $sysmis); + //} + $this->writeOpcode($buffer, self::OPCODE_EOF); } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { - $buffer->writeInt(self::TYPE); - $buffer->writeInt(0); - - if (! isset($buffer->context->variables)) { + if (!isset($buffer->context->variables)) { throw new \InvalidArgumentException('Variables required'); } - if (! isset($buffer->context->header)) { + + if (!isset($buffer->context->header)) { throw new \InvalidArgumentException('Header required'); } - if (! isset($buffer->context->info)) { + + if (!isset($buffer->context->info)) { throw new \InvalidArgumentException('Info required'); } @@ -207,87 +250,266 @@ public function write(Buffer $buffer) /** @var Record\Info[] $info */ $info = $buffer->context->info; + $veryLongStrings = array(); + if (isset($info[Record\Info\VeryLongString::SUBTYPE])) { + $veryLongStrings = $info[Record\Info\VeryLongString::SUBTYPE]->toArray(); + } + if (isset($info[Record\Info\MachineFloatingPoint::SUBTYPE])) { $sysmis = $info[Record\Info\MachineFloatingPoint::SUBTYPE]->sysmis; } else { $sysmis = NAN; } - $dataBuffer = Buffer::factory('', ['memory' => true]); - - for ($case = 0; $case < $casesCount; $case++) { - foreach ($variables as $index => $var) { - $value = $this->matrix[$case][$index]; - - // $isNumeric = $var->width == 0; - $isNumeric = $var->width === 0 && \SPSS\Sav\Variable::isNumberFormat($var->write[1]); - $width = isset($var->write[2]) ? $var->write[2] : $var->width; - - if ($isNumeric) { - if (! $compressed) { - $buffer->writeDouble($value); - } elseif ($value === $sysmis) { - $this->writeOpcode($buffer, $dataBuffer, self::OPCODE_SYSMISS); - } elseif ($value >= 1 - $bias && $value <= 251 - $bias && $value === (int) $value) { - $this->writeOpcode($buffer, $dataBuffer, $value + $bias); - } else { - $this->writeOpcode($buffer, $dataBuffer, self::OPCODE_RAW_DATA); - $dataBuffer->writeDouble($value); - } - } elseif (! $compressed) { - $buffer->writeString($value, Utils::roundUp($width, 8)); - } else { - $offset = 0; - $segmentsCount = Utils::widthToSegments($width); - for ($s = 0; $s < $segmentsCount; $s++) { - $segWidth = Utils::segmentAllocWidth($width, $s); - for ($i = $segWidth; $i > 0; $i -= 8, $offset += 8) { - // $chunkSize = min($i, 8); - $val = mb_substr($value, $offset, 8); - if ($val === "") { - $this->writeOpcode($buffer, $dataBuffer, self::OPCODE_WHITESPACES); - } else { - $this->writeOpcode($buffer, $dataBuffer, self::OPCODE_RAW_DATA); - $dataBuffer->writeString($val, 8); - } - } - } - } + $buffer->writeInt(self::TYPE); + $this->startData = $buffer->position(); + $buffer->writeInt(0); + $this->dataBuffer = Buffer::factory('', array('memory' => true)); + + if (\count($this->matrix) > 0) { + for ($case = 0; $case < $casesCount; ++$case) { + $row = $this->matrix[$case]; + $this->writeCaseData( + $buffer, + $row, + $compressed, + $bias, + $variables, + $veryLongStrings, + $sysmis + ); } } - $this->writeOpcode($buffer, $dataBuffer, self::OPCODE_EOF); + $this->writeOpcode($buffer, self::OPCODE_EOF); + } + + /** + * @return array + */ + public function toArray() + { + return $this->matrix; + } + + /** + * @return array + */ + public function getRow() + { + return $this->row; + } + + /** + * @return true|false + */ + public function close() + { + if (isset($this->dataBuffer)) { + return $this->dataBuffer->close(); + } + + return false; + } + + /** + * @return int + */ + protected function readOpcode(Buffer $buffer) + { + if ($this->opcodeIndex >= 8) { + $this->opcodes = $buffer->readBytes(8); + $this->opcodeIndex = 0; + } + + return 0xFF & $this->opcodes[$this->opcodeIndex++]; } /** - * @param Buffer $buffer - * @param Buffer $dataBuffer * @param int $opcode */ - public function writeOpcode(Buffer $buffer, Buffer $dataBuffer, $opcode) + protected function writeOpcode(Buffer $buffer, $opcode) { - if ($this->opcodeIndex >= 8 || $opcode == self::OPCODE_EOF) { + if ($this->opcodeIndex >= 8 || self::OPCODE_EOF === $opcode) { + $pos = $buffer->position(); foreach ($this->opcodes as $opc) { - $buffer->write(chr($opc)); + $buffer->write(\chr($opc)); } - $padding = max(8 - count($this->opcodes), 0); - for ($i = 0; $i < $padding; $i++) { - $buffer->write(chr(self::OPCODE_NOP)); + $padding = max(8 - \count($this->opcodes), 0); + for ($i = 0; $i < $padding; ++$i) { + $buffer->write(\chr(self::OPCODE_NOP)); } - $this->opcodes = []; - $this->opcodeIndex = 0; - $dataBuffer->rewind(); - $buffer->writeStream($dataBuffer->getStream()); - $dataBuffer->truncate(); + /* @noinspection NotOptimalIfConditionsInspection */ + if (self::OPCODE_EOF === $opcode) { + $dataPos = $this->dataBuffer->position(); + $this->dataBuffer->rewind(); + $buffer->writeStream($this->dataBuffer->getStream()); + $this->dataBuffer->seek($dataPos); + $buffer->seek($pos); + } else { + $this->opcodes = array(); + $this->opcodeIndex = 0; + $this->dataBuffer->rewind(); + $buffer->writeStream($this->dataBuffer->getStream()); + $this->dataBuffer->truncate(); + } + } + + if (self::OPCODE_EOF !== $opcode) { + $this->opcodes[$this->opcodeIndex++] = 0xFF & $opcode; } - $this->opcodes[$this->opcodeIndex++] = 0xFF & $opcode; } /** + * @param bool $compressed + * @param int $bias + * @param array $variables + * @param array $veryLongStrings + * @param int $sysmis + * + * @throws Exception + * * @return array */ - public function toArray() + protected function readCaseData(Buffer $buffer, $compressed, $bias, $variables, $veryLongStrings, $sysmis) { - return $this->matrix; + $result = array(); + $varCount = \count($variables); + $varNum = 0; + + for ($index = 0; $index < $varCount; ++$index) { + $var = $variables[$index]; + $isNumeric = 0 === $var->width && \SPSS\Sav\Variable::isNumberFormat($var->write[1]); + $width = isset($var->write[2]) ? $var->write[2] : $var->width; + + // var_dump($var); + // exit; + + if ($isNumeric) { + if (!$compressed) { + $result[$varNum] = $buffer->readDouble(); + } else { + $opcode = $this->readOpcode($buffer); + switch ($opcode) { + case self::OPCODE_NOP: + break; + case self::OPCODE_EOF: + throw new Exception('Error reading data: unexpected end of compressed data file (cluster code 252)'); + break; + case self::OPCODE_RAW_DATA: + $result[$varNum] = $buffer->readDouble(); + break; + case self::OPCODE_SYSMISS: + $result[$varNum] = $sysmis; + break; + default: + $result[$varNum] = $opcode - $bias; + break; + } + } + } else { + $width = isset($veryLongStrings[$var->name]) ? $veryLongStrings[$var->name] : $width; + $result[$varNum] = ''; + $segmentsCount = Utils::widthToSegments($width); + $opcode = self::OPCODE_RAW_DATA; + for ($s = 0; $s < $segmentsCount; ++$s) { + $segWidth = Utils::segmentAllocWidth($width, $s); + if (self::OPCODE_NOP === $opcode || self::OPCODE_EOF === $opcode) { + // If next segments are empty too, skip + continue; + } + for ($i = $segWidth; $i > 0; $i -= 8) { + if ($segWidth = 255) { + $chunkSize = min($i, 8); + } else { + $chunkSize = 8; + } + + $val = ''; + if (!$compressed) { + $val = $buffer->readString(8); + } else { + $opcode = $this->readOpcode($buffer); + switch ($opcode) { + case self::OPCODE_NOP: + break 2; + case self::OPCODE_EOF: + throw new Exception('Error reading data: unexpected end of compressed data file (cluster code 252)'); + break 2; + case self::OPCODE_RAW_DATA: + $val = $buffer->readString(8); + break; + case self::OPCODE_WHITESPACES: + $val = ' '; + break; + } + } + $result[$varNum] .= $val; + } + $result[$varNum] = rtrim($result[$varNum]); + } + } + ++$varNum; + } + + return $result; + } + + /** + * @param array $row + * @param bool $compressed + * @param int $bias + * @param array $variables + * @param array $veryLongStrings + * @param int $sysmis + * + * @throws Exception + */ + protected function writeCaseData(Buffer $buffer, $row, $compressed, $bias, $variables, $veryLongStrings, $sysmis) + { + foreach ($variables as $index => $var) { + $value = $row[$index]; + + // $isNumeric = $var->width == 0; + $isNumeric = 0 === $var->width && \SPSS\Sav\Variable::isNumberFormat($var->write[1]); + $width = isset($var->write[2]) ? $var->write[2] : $var->width; + + if ($isNumeric) { + if (!$compressed) { + $buffer->writeDouble($value); + } elseif ($value === $sysmis || '' === $value) { + $this->writeOpcode($buffer, self::OPCODE_SYSMISS); + } elseif ($value >= 1 - $bias && $value <= 251 - $bias && $value === (int) $value) { + $this->writeOpcode($buffer, $value + $bias); + } else { + $this->writeOpcode($buffer, self::OPCODE_RAW_DATA); + $this->dataBuffer->writeDouble($value); + } + } elseif (!$compressed) { + $buffer->writeString($value, Utils::roundUp($width, 8)); + } else { + $offset = 0; + $width = isset($veryLongStrings[$var->name]) ? $veryLongStrings[$var->name] : $width; + $segmentsCount = Utils::widthToSegments($width); + for ($s = 0; $s < $segmentsCount; ++$s) { + $segWidth = Utils::segmentAllocWidth($width, $s); + for ($i = $segWidth; $i > 0; $i -= 8) { + if ($segWidth = 255) { + $chunkSize = min($i, 8); + } else { + $chunkSize = 8; + } + $val = substr($value, $offset, $chunkSize); // Read 8 byte segements, don't use mbsubstr here + if ('' === $val) { + $this->writeOpcode($buffer, self::OPCODE_WHITESPACES); + } else { + $this->writeOpcode($buffer, self::OPCODE_RAW_DATA); + $this->dataBuffer->writeString($val, 8); + } + $offset += $chunkSize; + } + } + } + } } } diff --git a/src/Sav/Record/Document.php b/src/Sav/Record/Document.php index 3b932e7..deeecd5 100644 --- a/src/Sav/Record/Document.php +++ b/src/Sav/Record/Document.php @@ -13,26 +13,20 @@ class Document extends Record implements \ArrayAccess /** * @var array */ - protected $lines = []; + protected $lines = array(); - /** - * @param Buffer $buffer - */ public function read(Buffer $buffer) { $count = $buffer->readInt(); - for ($i = 0; $i < $count; $i++) { + for ($i = 0; $i < $count; ++$i) { $this->lines[] = trim($buffer->readString(self::LENGTH)); } } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { $buffer->writeInt(self::TYPE); - $buffer->writeInt(count($this->lines)); + $buffer->writeInt(\count($this->lines)); foreach ($this->lines as $line) { $buffer->writeString((string) $line, self::LENGTH); } @@ -58,6 +52,7 @@ public function append($lines) /** * @param mixed $offset + * * @return bool */ public function offsetExists($offset) @@ -67,6 +62,7 @@ public function offsetExists($offset) /** * @param mixed $offset + * * @return mixed */ public function offsetGet($offset) diff --git a/src/Sav/Record/Header.php b/src/Sav/Record/Header.php index e4f06ee..ca57d6a 100644 --- a/src/Sav/Record/Header.php +++ b/src/Sav/Record/Header.php @@ -31,7 +31,7 @@ class Header extends Record public $prodName = '@(#) SPSS DATA FILE'; /** - * @var int Normally set to 2, although a few system files have been spotted in the wild with a value of 3 here. + * @var int normally set to 2, although a few system files have been spotted in the wild with a value of 3 here */ public $layoutCode = 2; @@ -99,13 +99,12 @@ class Header extends Record public $fileLabel; /** - * @param Buffer $buffer * @throws Exception */ public function read(Buffer $buffer) { $this->recType = $buffer->readString(4); - if (! ($this->recType === self::NORMAL_REC_TYPE || $this->recType === self::ZLIB_REC_TYPE)) { + if (!(self::NORMAL_REC_TYPE === $this->recType || self::ZLIB_REC_TYPE === $this->recType)) { throw new Exception('Read header error: this is not a valid SPSS file. Does not start with $FL2 or $FL3.'); } $this->prodName = trim($buffer->readString(60)); @@ -113,7 +112,7 @@ public function read(Buffer $buffer) // layoutCode should be 2 or 3. // If not swap bytes and check again which would then indicate big-endian - if ($this->layoutCode !== 2 && $this->layoutCode !== 3) { + if (2 !== $this->layoutCode && 3 !== $this->layoutCode) { // try to flip to big-endian mode and read again $buffer->isBigEndian = true; $buffer->skip(-4); @@ -133,9 +132,6 @@ public function read(Buffer $buffer) $buffer->skip(3); } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { $buffer->write($this->recType); @@ -151,4 +147,16 @@ public function write(Buffer $buffer) $buffer->writeString($this->fileLabel, 64); $buffer->writeNull(3); } + + public function increaseCasesCount(Buffer $buffer) + { + // Jump to the position of the casesCount in the header, re-write it and keep the current position. + // recType + prodName + layoutCode + nominalCaseSize + compression + weightIndex + // 4 + 60 + 4 + 4 + 4 + 4 = 80 + ++$this->casesCount; + $pos = $buffer->position(); + $buffer->seek(80); + $buffer->writeInt($this->casesCount); + $buffer->seek($pos); + } } diff --git a/src/Sav/Record/Info.php b/src/Sav/Record/Info.php index ae0beb6..6a6b6ed 100644 --- a/src/Sav/Record/Info.php +++ b/src/Sav/Record/Info.php @@ -13,7 +13,7 @@ class Info extends Record implements \ArrayAccess /** * @var array */ - protected $data = []; + protected $data = array(); /** * @var int Size of each piece of data in the data part, in bytes @@ -25,18 +25,12 @@ class Info extends Record implements \ArrayAccess */ protected $dataCount = 0; - /** - * @param Buffer $buffer - */ public function read(Buffer $buffer) { $this->dataSize = $buffer->readInt(); $this->dataCount = $buffer->readInt(); } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { $buffer->writeInt(self::TYPE); @@ -55,6 +49,7 @@ public function toArray() /** * @param mixed $offset + * * @return bool */ public function offsetExists($offset) @@ -64,6 +59,7 @@ public function offsetExists($offset) /** * @param mixed $offset + * * @return mixed */ public function offsetGet($offset) @@ -77,7 +73,11 @@ public function offsetGet($offset) */ public function offsetSet($offset, $value) { - $this->data[$offset] = $value; + if (null === $offset) { + $this->data[] = $value; + } else { + $this->data[$offset] = $value; + } } /** diff --git a/src/Sav/Record/Info/CharacterEncoding.php b/src/Sav/Record/Info/CharacterEncoding.php index a6cb8e1..dc573cf 100644 --- a/src/Sav/Record/Info/CharacterEncoding.php +++ b/src/Sav/Record/Info/CharacterEncoding.php @@ -15,20 +15,25 @@ class CharacterEncoding extends Info public $value; /** - * @param Buffer $buffer + * Record constructor. + * + * @param array $data + * @param mixed $value */ + public function __construct($value) + { + $this->value = $value; + } + public function read(Buffer $buffer) { parent::read($buffer); $this->value = $buffer->readString($this->dataSize * $this->dataCount); } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { - $this->dataCount = strlen($this->value); + $this->dataCount = \strlen($this->value); parent::write($buffer); $buffer->writeString($this->value); } diff --git a/src/Sav/Record/Info/ExtendedNumberOfCases.php b/src/Sav/Record/Info/ExtendedNumberOfCases.php index d1f63e9..3bded38 100644 --- a/src/Sav/Record/Info/ExtendedNumberOfCases.php +++ b/src/Sav/Record/Info/ExtendedNumberOfCases.php @@ -10,7 +10,7 @@ class ExtendedNumberOfCases extends Info const SUBTYPE = 16; /** - * @var double + * @var float */ public $ncases = 0; @@ -24,9 +24,6 @@ class ExtendedNumberOfCases extends Info */ protected $dataCount = 2; - /** - * @param Buffer $buffer - */ public function read(Buffer $buffer) { parent::read($buffer); @@ -34,9 +31,6 @@ public function read(Buffer $buffer) $this->ncases = $buffer->readDouble(); } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { parent::write($buffer); diff --git a/src/Sav/Record/Info/LongStringMissingValues.php b/src/Sav/Record/Info/LongStringMissingValues.php index 5030358..e523f71 100644 --- a/src/Sav/Record/Info/LongStringMissingValues.php +++ b/src/Sav/Record/Info/LongStringMissingValues.php @@ -10,7 +10,6 @@ class LongStringMissingValues extends Info const SUBTYPE = 22; /** - * @param Buffer $buffer * @throws \SPSS\Exception */ public function read(Buffer $buffer) @@ -19,19 +18,16 @@ public function read(Buffer $buffer) $buffer = $buffer->allocate($this->dataCount * $this->dataSize); while ($varNameLength = $buffer->readInt()) { $varName = trim($buffer->readString($varNameLength)); - $count = ord($buffer->read(1)); - $this->data[$varName] = []; + $count = \ord($buffer->read(1)); + $this->data[$varName] = array(); $valueLength = $buffer->readInt(); - for ($i = 0; $i < $count; $i++) { + for ($i = 0; $i < $count; ++$i) { $value = $buffer->readString($valueLength); $this->data[$varName][] = rtrim($value); } } } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { if ($this->data) { @@ -39,7 +35,7 @@ public function write(Buffer $buffer) foreach ($this->data as $varName => $values) { $localBuffer->writeInt(mb_strlen($varName)); $localBuffer->writeString($varName); - $localBuffer->write(chr(count($values)), 1); + $localBuffer->write(\chr(\count($values)), 1); $localBuffer->writeInt(8); foreach ($values as $value) { $localBuffer->writeString($value, 8); diff --git a/src/Sav/Record/Info/LongStringValueLabels.php b/src/Sav/Record/Info/LongStringValueLabels.php index d4e5226..33bee82 100644 --- a/src/Sav/Record/Info/LongStringValueLabels.php +++ b/src/Sav/Record/Info/LongStringValueLabels.php @@ -12,10 +12,9 @@ class LongStringValueLabels extends Info /** * @var array */ - public $data = []; + public $data = array(); /** - * @param Buffer $buffer * @throws \SPSS\Exception */ public function read(Buffer $buffer) @@ -26,11 +25,11 @@ public function read(Buffer $buffer) $varName = $buffer->readString($varNameLength); $varWidth = $buffer->readInt(); // The width of the variable, in bytes, which will be between 9 and 32767 $valuesCount = $buffer->readInt(); - $this->data[$varName] = [ + $this->data[$varName] = array( 'width' => $varWidth, - 'values' => [], - ]; - for ($i = 0; $i < $valuesCount; $i++) { + 'values' => array(), + ); + for ($i = 0; $i < $valuesCount; ++$i) { $valueLength = $buffer->readInt(); $value = rtrim($buffer->readString($valueLength)); $labelLength = $buffer->readInt(); @@ -40,24 +39,21 @@ public function read(Buffer $buffer) } } - /** - * @param \SPSS\Buffer $buffer - */ public function write(Buffer $buffer) { - $localBuffer = Buffer::factory('', ['memory' => true]); + $localBuffer = Buffer::factory('', array('memory' => true)); foreach ($this->data as $varName => $data) { - if (! isset($data['width'])) { + if (!isset($data['width'])) { throw new \InvalidArgumentException('width required'); } - if (! isset($data['values'])) { + if (!isset($data['values'])) { throw new \InvalidArgumentException('values required'); } $width = (int) $data['width']; $localBuffer->writeInt(mb_strlen($varName)); $localBuffer->writeString($varName); $localBuffer->writeInt($width); - $localBuffer->writeInt(count($data['values'])); + $localBuffer->writeInt(\count($data['values'])); foreach ($data['values'] as $value => $label) { $localBuffer->writeInt($width); $localBuffer->writeString($value, $width); diff --git a/src/Sav/Record/Info/LongVariableNames.php b/src/Sav/Record/Info/LongVariableNames.php index 75bafe6..1af6eb5 100644 --- a/src/Sav/Record/Info/LongVariableNames.php +++ b/src/Sav/Record/Info/LongVariableNames.php @@ -13,11 +13,8 @@ class LongVariableNames extends Info /** * @var array */ - public $data = []; + public $data = array(); - /** - * @param Buffer $buffer - */ public function read(Buffer $buffer) { parent::read($buffer); @@ -29,16 +26,13 @@ public function read(Buffer $buffer) } } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { $data = ''; foreach ($this->data as $key => $value) { - $data .= sprintf('%s=%s', $key, $value).self::DELIMITER; + $data .= sprintf('%s=%s', $key, $value) . self::DELIMITER; } - $this->dataCount = strlen($data); + $this->dataCount = \strlen($data); parent::write($buffer); $buffer->writeString($data); } diff --git a/src/Sav/Record/Info/MachineFloatingPoint.php b/src/Sav/Record/Info/MachineFloatingPoint.php index 00dcb71..b9f505d 100644 --- a/src/Sav/Record/Info/MachineFloatingPoint.php +++ b/src/Sav/Record/Info/MachineFloatingPoint.php @@ -6,8 +6,8 @@ use SPSS\Sav\Record\Info; // Available as of PHP 7.2.0. -if (! defined('PHP_FLOAT_MAX')) { - define('PHP_FLOAT_MAX', 1.7976931348623e+308); +if (!\defined('PHP_FLOAT_MAX')) { + \define('PHP_FLOAT_MAX', 1.7976931348623e+308); } class MachineFloatingPoint extends Info @@ -15,33 +15,30 @@ class MachineFloatingPoint extends Info const SUBTYPE = 4; /** - * @var double + * @var float */ public $sysmis; /** - * @var double + * @var float */ public $highest; /** - * @var double + * @var float */ public $lowest; /** - * @var int Always set to 8. + * @var int always set to 8 */ protected $dataSize = 8; /** - * @var int Always set to 3. + * @var int always set to 3 */ protected $dataCount = 3; - /** - * @param Buffer $buffer - */ public function read(Buffer $buffer) { parent::read($buffer); @@ -50,20 +47,17 @@ public function read(Buffer $buffer) $this->lowest = $buffer->readDouble(); } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { - if (! $this->sysmis) { + if (!$this->sysmis) { $this->sysmis = -PHP_FLOAT_MAX; } - if (! $this->highest) { + if (!$this->highest) { $this->highest = PHP_FLOAT_MAX; } - if (! $this->lowest) { + if (!$this->lowest) { $this->lowest = -PHP_FLOAT_MAX; } diff --git a/src/Sav/Record/Info/MachineInteger.php b/src/Sav/Record/Info/MachineInteger.php index d1208b3..ff638c4 100644 --- a/src/Sav/Record/Info/MachineInteger.php +++ b/src/Sav/Record/Info/MachineInteger.php @@ -12,10 +12,10 @@ class MachineInteger extends Info /** * @var array [Major, Minor, Revision] */ - public $version = [1, 0, 0]; + public $version = array(1, 0, 0); /** - * @var int Machine code. + * @var int machine code */ public $machineCode = 0; @@ -55,22 +55,19 @@ class MachineInteger extends Info public $characterCode = 65001; /** - * @var int Always set to 4. + * @var int always set to 4 */ protected $dataSize = 4; /** - * @var int Always set to 8. + * @var int always set to 8 */ protected $dataCount = 8; - /** - * @param Buffer $buffer - */ public function read(Buffer $buffer) { parent::read($buffer); - $this->version = [$buffer->readInt(), $buffer->readInt(), $buffer->readInt()]; + $this->version = array($buffer->readInt(), $buffer->readInt(), $buffer->readInt()); $this->machineCode = $buffer->readInt(); $this->floatingPointRep = $buffer->readInt(); $this->compressionCode = $buffer->readInt(); @@ -78,9 +75,6 @@ public function read(Buffer $buffer) $this->characterCode = $buffer->readInt(); } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { parent::write($buffer); diff --git a/src/Sav/Record/Info/Unknown.php b/src/Sav/Record/Info/Unknown.php index 2288909..f5d7901 100644 --- a/src/Sav/Record/Info/Unknown.php +++ b/src/Sav/Record/Info/Unknown.php @@ -7,24 +7,18 @@ class Unknown extends Info { - /** - * @param Buffer $buffer - */ public function read(Buffer $buffer) { parent::read($buffer); $this->data['raw'] = $buffer->readString($this->dataSize * $this->dataCount); } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { - if (! isset($this->data['raw'])) { + if (!isset($this->data['raw'])) { $this->data['raw'] = ''; } - $this->dataCount = strlen($this->data['raw']); + $this->dataCount = \strlen($this->data['raw']); parent::write($buffer); $buffer->writeString($this->data['raw']); } diff --git a/src/Sav/Record/Info/VariableAttributes.php b/src/Sav/Record/Info/VariableAttributes.php index e747d26..0f3285c 100644 --- a/src/Sav/Record/Info/VariableAttributes.php +++ b/src/Sav/Record/Info/VariableAttributes.php @@ -12,11 +12,8 @@ class VariableAttributes extends Info /** * @var array */ - public $data = []; + public $data = array(); - /** - * @param Buffer $buffer - */ public function read(Buffer $buffer) { parent::read($buffer); @@ -24,7 +21,7 @@ public function read(Buffer $buffer) foreach (explode('/', $data) as $item) { list($var, $value) = explode(':', $item); if (preg_match_all('#(.+)\((.+)\)#Uis', $value, $matches)) { - $this->data[$var] = []; + $this->data[$var] = array(); foreach ($matches[1] as $key => $val) { $this->data[$var][$val] = trim(trim($matches[2][$key]), '\''); } @@ -34,14 +31,11 @@ public function read(Buffer $buffer) } } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { - $lines = []; + $lines = array(); foreach ($this->data as $var => $value) { - if (is_array($value)) { + if (\is_array($value)) { $_tmpString = ''; foreach ($value as $key => $val) { $_tmpString .= sprintf("%s('%s'\n)", $key, $val); diff --git a/src/Sav/Record/Info/VariableDisplayParam.php b/src/Sav/Record/Info/VariableDisplayParam.php index 6dc76a3..fd0b654 100644 --- a/src/Sav/Record/Info/VariableDisplayParam.php +++ b/src/Sav/Record/Info/VariableDisplayParam.php @@ -13,7 +13,7 @@ class VariableDisplayParam extends Info /** * @var array */ - public $data = []; + public $data = array(); /** * @var int @@ -21,43 +21,31 @@ class VariableDisplayParam extends Info protected $dataSize = 4; /** - * @param Buffer $buffer * @throws Exception */ public function read(Buffer $buffer) { parent::read($buffer); - if ($this->dataSize !== 4) { - throw new Exception( - sprintf('Error reading record type 7 subtype 11: bad data element length [%s]. Expecting 4.', - $this->dataSize - ) - ); + if (4 !== $this->dataSize) { + throw new Exception(sprintf('Error reading record type 7 subtype 11: bad data element length [%s]. Expecting 4.', $this->dataSize)); } - if (($this->dataCount % 3) !== 0) { - throw new Exception( - sprintf('Error reading record type 7 subtype 11: number of data elements [%s] is not a multiple of 3.', - $this->dataCount - ) - ); + if (0 !== ($this->dataCount % 3)) { + throw new Exception(sprintf('Error reading record type 7 subtype 11: number of data elements [%s] is not a multiple of 3.', $this->dataCount)); } $itemCount = $this->dataCount / 3; - for ($i = 0; $i < $itemCount; $i++) { - $this->data[] = [ + for ($i = 0; $i < $itemCount; ++$i) { + $this->data[] = array( $buffer->readInt(), // The measurement type of the variable $buffer->readInt(), // The width of the display column for the variable in characters. $buffer->readInt(), // The alignment of the variable - ]; + ); } } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { if ($this->data) { - $this->dataCount = count($this->data) * 3; + $this->dataCount = \count($this->data) * 3; parent::write($buffer); foreach ($this->data as $item) { $buffer->writeInt(0xFF & $item[0]); diff --git a/src/Sav/Record/Info/VeryLongString.php b/src/Sav/Record/Info/VeryLongString.php index a34244c..32dbc7b 100644 --- a/src/Sav/Record/Info/VeryLongString.php +++ b/src/Sav/Record/Info/VeryLongString.php @@ -10,9 +10,6 @@ class VeryLongString extends Info const SUBTYPE = 14; const DELIMITER = "\t"; - /** - * @param Buffer $buffer - */ public function read(Buffer $buffer) { parent::read($buffer); @@ -23,17 +20,15 @@ public function read(Buffer $buffer) } } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { if ($this->data) { - $data = ''; + $data = array(); foreach ($this->data as $key => $value) { - $data .= sprintf('%s=%05d%c', $key, $value, 0).self::DELIMITER; + $data[] = sprintf('%s=%05d%c', $key, $value, 0); } - $this->dataCount = strlen($data); + $data = implode(self::DELIMITER, $data); + $this->dataCount = \strlen($data); parent::write($buffer); $buffer->writeString($data); } diff --git a/src/Sav/Record/InfoCollection.php b/src/Sav/Record/InfoCollection.php index f96d836..93ca735 100644 --- a/src/Sav/Record/InfoCollection.php +++ b/src/Sav/Record/InfoCollection.php @@ -10,7 +10,7 @@ class InfoCollection /** * @var array */ - public static $classMap = [ + public static $classMap = array( Record\Info\MachineInteger::class, Record\Info\MachineFloatingPoint::class, Record\Info\VariableDisplayParam::class, @@ -22,15 +22,16 @@ class InfoCollection Record\Info\CharacterEncoding::class, Record\Info\LongStringValueLabels::class, Record\Info\LongStringMissingValues::class, - ]; + ); /** * @var array */ - public $data = []; + public $data = array(); /** * @param int $subtype + * * @return string */ protected static function getClassBySubtype($subtype) @@ -45,13 +46,12 @@ protected static function getClassBySubtype($subtype) } /** - * @param Buffer $buffer * @return array|Record */ public function fill(Buffer $buffer) { $subtype = $buffer->readInt(); - $this->data[$subtype] = call_user_func(self::getClassBySubtype($subtype).'::fill', $buffer); + $this->data[$subtype] = \call_user_func(self::getClassBySubtype($subtype) . '::fill', $buffer); return $this->data; } diff --git a/src/Sav/Record/ValueLabel.php b/src/Sav/Record/ValueLabel.php index 1f4313c..c62ee0b 100644 --- a/src/Sav/Record/ValueLabel.php +++ b/src/Sav/Record/ValueLabel.php @@ -9,7 +9,7 @@ /** * The value label records documented in this section are used for numeric and short string variables only. - * Long string variables may have value labels, but their value labels are recorded using a different record type + * Long string variables may have value labels, but their value labels are recorded using a different record type. * * @see Info\LongStringValueLabels */ @@ -21,19 +21,19 @@ class ValueLabel extends Record /** * @var array */ - public $labels = []; + public $labels = array(); /** * @var array * A list of dictionary indexes of variables to which to apply the value labels - * String variables wider than 8 bytes may not be specified in this list. + * String variables wider than 8 bytes may not be specified in this list */ - public $indexes = []; + public $indexes = array(); /** * @var Variable[] */ - protected $variables = []; + protected $variables = array(); /** * @param array $variables @@ -44,7 +44,6 @@ public function setVariables($variables) } /** - * @param Buffer $buffer * @throws Exception */ public function read(Buffer $buffer) @@ -52,29 +51,26 @@ public function read(Buffer $buffer) /** @var int $labelCount Number of value labels present in this record. */ $labelCount = $buffer->readInt(); - for ($i = 0; $i < $labelCount; $i++) { + for ($i = 0; $i < $labelCount; ++$i) { // A numeric value or a short string value padded as necessary to 8 bytes in length. $value = $buffer->readDouble(); - $labelLength = ord($buffer->read(1)); + $labelLength = \ord($buffer->read(1)); $label = $buffer->readString(Utils::roundUp($labelLength + 1, 8) - 1); - $this->labels[] = [ + $this->labels[] = array( 'value' => $value, 'label' => rtrim($label), - ]; + ); } // The value label variables record is always immediately followed after a value label record. $recType = $buffer->readInt(); - if ($recType !== 4) { - throw new Exception( - sprintf('Error reading Variable Index record: bad record type [%s]. Expecting Record Type 4.', $recType) - ); + if (4 !== $recType) { + throw new Exception(sprintf('Error reading Variable Index record: bad record type [%s]. Expecting Record Type 4.', $recType)); } // Number of variables that the associated value labels from the value label record are to be applied. $varCount = $buffer->readInt(); - for ($i = 0; $i < $varCount; $i++) { - + for ($i = 0; $i < $varCount; ++$i) { $varIndex = $buffer->readInt() - 1; // Decode values for short variables @@ -89,40 +85,42 @@ public function read(Buffer $buffer) $this->indexes[] = $varIndex; } - } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { $convertToDouble = false; $varIndex = reset($this->indexes); - if ($varIndex !== false && isset($this->variables[$varIndex - 1])) { + if (false !== $varIndex && isset($this->variables[$varIndex - 1])) { $varWidth = $this->variables[$varIndex - 1]->width; $convertToDouble = $varWidth > 0; } // Value label record. $buffer->writeInt(self::TYPE); - $buffer->writeInt(count($this->labels)); + $buffer->writeInt(\count($this->labels)); foreach ($this->labels as $item) { - $labelLength = mb_strlen($item['label']); - $labelLength = min($labelLength, self::LABEL_MAX_LENGTH); + $labelLength = min(mb_strlen($item['label']), self::LABEL_MAX_LENGTH); + $label = mb_substr($item['label'], 0, $labelLength); + $labelLengthBytes = mb_strlen($label, '8bit'); + while ($labelLengthBytes > 255) { + // Strip one char, can be multiple bytes + $label = mb_substr($label, 0, -1); + $labelLengthBytes = mb_strlen($label, '8bit'); + } if ($convertToDouble) { $item['value'] = Utils::stringToDouble($item['value']); } $buffer->writeDouble($item['value']); - $buffer->write(chr($labelLength)); - $buffer->writeString($item['label'], Utils::roundUp($labelLength + 1, 8) - 1); + $buffer->write(\chr($labelLengthBytes)); + $buffer->writeString($label, Utils::roundUp($labelLengthBytes + 1, 8) - 1); } // Value label variable record. $buffer->writeInt(4); - $buffer->writeInt(count($this->indexes)); + $buffer->writeInt(\count($this->indexes)); foreach ($this->indexes as $varIndex) { $buffer->writeInt($varIndex); } diff --git a/src/Sav/Record/Variable.php b/src/Sav/Record/Variable.php index 6ccdf5f..3bbd91a 100644 --- a/src/Sav/Record/Variable.php +++ b/src/Sav/Record/Variable.php @@ -25,45 +25,51 @@ class Variable extends Record * For a short string variable or the first part of a long string variable, this is set to the width of the string. * For the second and subsequent parts of a long string variable, set to -1, and the remaining fields in the structure are ignored. * - * @var int Variable width. + * @var int variable width */ public $width; + /** + * The real record position of the variable inside the file. + */ + public $realPosition; + /** * If the variable has no missing values, set to 0. * If the variable has one, two, or three discrete missing values, set to 1, 2, or 3, respectively. * If the variable has a range for missing variables, set to -2; * if the variable has a range for missing variables plus a single discrete value, set to -3. * A long string variable always has the value 0 here. - * A separate record indicates missing values for long string variables + * A separate record indicates missing values for long string variables. * * @var int + * * @see \SPSS\Sav\Record\Info\LongStringMissingValues */ public $missingValuesFormat = 0; /** * Print format for this variable. - * [decimals, width, format, 0] + * [decimals, width, format, 0]. * * @var array */ - public $print = [0, 0, 0, 0]; + public $print = array(0, 0, 0, 0); /** * Write format for this variable. - * [decimals, width, format, 0] + * [decimals, width, format, 0]. * * @var array */ - public $write = [0, 0, 0, 0]; + public $write = array(0, 0, 0, 0); /** * The variable name must begin with a capital letter or the at-sign (‘@’). * Subsequent characters may also be digits, octothorpes (‘#’), dollar signs (‘$’), underscores (‘_’), or full stops (‘.’). * The variable name is padded on the right with spaces. * - * @var string Variable name. + * @var string variable name */ public $name; @@ -88,12 +94,13 @@ class Variable extends Record * * @var array */ - public $missingValues = []; + public $missingValues = array(); /** * Returns true if WIDTH is a very long string width, false otherwise. * * @param int $width + * * @return int */ public static function isVeryLong($width) @@ -101,9 +108,6 @@ public static function isVeryLong($width) return $width > self::REAL_VLS_CHUNK; } - /** - * @param Buffer $buffer - */ public function read(Buffer $buffer) { $this->width = $buffer->readInt(); @@ -116,20 +120,17 @@ public function read(Buffer $buffer) $labelLength = $buffer->readInt(); $this->label = $buffer->readString($labelLength, 4); } - if ($this->missingValuesFormat !== 0) { - for ($i = 0, $iMax = abs($this->missingValuesFormat); $i < $iMax; $i++) { + if (0 !== $this->missingValuesFormat) { + for ($i = 0, $iMax = abs($this->missingValuesFormat); $i < $iMax; ++$i) { $this->missingValues[] = $buffer->readDouble(); } } } - /** - * @param Buffer $buffer - */ public function write(Buffer $buffer) { $seg0width = Utils::segmentAllocWidth($this->width, 0); - $hasLabel = ! empty($this->label); + $hasLabel = !empty($this->label); $buffer->writeInt(self::TYPE); $buffer->writeInt($seg0width); @@ -140,15 +141,23 @@ public function write(Buffer $buffer) $buffer->writeString($this->name, 8); if ($hasLabel) { + // Maxlength is 255 bytes, since we write utf8 a char can be multiple bytes $labelLength = min(mb_strlen($this->label), 255); - $buffer->writeInt($labelLength); - $buffer->writeString($this->label, Utils::roundUp($labelLength, 4)); + $label = mb_substr($this->label, 0, $labelLength); + $labelLengthBytes = mb_strlen($label, '8bit'); + while ($labelLengthBytes > 255) { + // Strip one char, can be multiple bytes + $label = mb_substr($label, 0, -1); + $labelLengthBytes = mb_strlen($label, '8bit'); + } + $buffer->writeInt($labelLengthBytes); + $buffer->writeString($label, Utils::roundUp($labelLengthBytes, 4)); } // TODO: test if ($this->missingValuesFormat) { foreach ($this->missingValues as $val) { - if ($this->width === 0) { + if (0 === $this->width) { $buffer->writeDouble($val); } else { $buffer->writeString($val, 8); @@ -156,22 +165,26 @@ public function write(Buffer $buffer) } } + // We need an empty record $this->writeBlank($buffer, $seg0width); // Write additional segments for very long string variables. if (self::isVeryLong($this->width)) { $segmentCount = Utils::widthToSegments($this->width); - for ($i = 1; $i < $segmentCount; $i++) { + for ($i = 1; $i < $segmentCount; ++$i) { $segmentWidth = Utils::segmentAllocWidth($this->width, $i); - $format = Utils::bytesToInt([0, max($segmentWidth, 1), 1, 0]); - + $format = Utils::bytesToInt(array(0, 1, max($segmentWidth, 1), 0)); $buffer->writeInt(self::TYPE); $buffer->writeInt($segmentWidth); - $buffer->writeInt(0); // No variable label + $buffer->writeInt($hasLabel); // No variable label $buffer->writeInt(0); // No missing values $buffer->writeInt($format); // Print format $buffer->writeInt($format); // Write format - $buffer->writeString($this->getSegmentName($i), 8); + $buffer->writeString($this->getSegmentName($i - 1), 8); + if ($hasLabel) { + $buffer->writeInt($labelLengthBytes); + $buffer->writeString($label, Utils::roundUp($labelLengthBytes, 4)); + } $this->writeBlank($buffer, $segmentWidth); } @@ -179,7 +192,6 @@ public function write(Buffer $buffer) } /** - * @param Buffer $buffer * @param int $width */ public function writeBlank(Buffer $buffer, $width) @@ -199,14 +211,15 @@ public function writeBlank(Buffer $buffer, $width) /** * @param int $seg + * * @return string */ public function getSegmentName($seg = 0) { // TODO: refactory $name = $this->name; - $name = mb_substr($name, 0, 8); - $name = mb_substr($name, 0, -mb_strlen($seg)).$seg; + $name = mb_substr($name, 0, 6); + $name .= $seg; return mb_strtoupper($name); } diff --git a/src/Sav/RecordInterface.php b/src/Sav/RecordInterface.php index 5a080d3..fde7ed9 100644 --- a/src/Sav/RecordInterface.php +++ b/src/Sav/RecordInterface.php @@ -4,7 +4,7 @@ use SPSS\Buffer; -Interface RecordInterface +interface RecordInterface { /** * @var int Record type code @@ -12,13 +12,11 @@ const TYPE = 0; /** - * @param Buffer $buffer * @return void */ public function read(Buffer $buffer); /** - * @param Buffer $buffer * @return void */ public function write(Buffer $buffer); diff --git a/src/Sav/Variable.php b/src/Sav/Variable.php index a0ba8f0..1789f27 100644 --- a/src/Sav/Variable.php +++ b/src/Sav/Variable.php @@ -68,27 +68,27 @@ class Variable public $measure; public $role; public $label; - public $values = []; - public $missing = []; + public $values = array(); + public $missing = array(); /** * @var array */ - public $attributes = [ + public $attributes = array( // '$@Role' => self::ROLE_BOTH - ]; + ); /** * @var array */ - public $data = []; + public $data = array(); /** * Variable constructor. * * @param array $data */ - public function __construct($data = []) + public function __construct($data = array()) { foreach ($data as $key => $value) { $this->{$key} = $value; @@ -97,17 +97,18 @@ public function __construct($data = []) /** * @param int $format + * * @return bool */ public static function isNumberFormat($format) { - return in_array($format, [ + return \in_array($format, array( self::FORMAT_TYPE_COMMA, self::FORMAT_TYPE_F, self::FORMAT_TYPE_DATETIME, self::FORMAT_TYPE_DATE, - self::FORMAT_TYPE_TIME - ], true); + self::FORMAT_TYPE_TIME, + ), true); } /** @@ -116,91 +117,93 @@ public static function isNumberFormat($format) * (string <= 8 chars) and a meaning (long string). * Non-existent codes have a (null, null) tuple returned. * - * @param integer $format + * @param int $format + * * @return array */ public static function getFormatInfo($format) { switch ($format) { case 0: - return ['', 'Continuation of string variable']; + return array('', 'Continuation of string variable'); case self::FORMAT_TYPE_A: - return ['A', 'Alphanumeric']; + return array('A', 'Alphanumeric'); case self::FORMAT_TYPE_AHEX: - return ['AHEX', 'alphanumeric hexadecimal']; + return array('AHEX', 'alphanumeric hexadecimal'); case self::FORMAT_TYPE_COMMA: - return ['COMMA', 'F format with commas']; + return array('COMMA', 'F format with commas'); case self::FORMAT_TYPE_DOLLAR: - return ['DOLLAR', 'Commas and floating point dollar sign']; + return array('DOLLAR', 'Commas and floating point dollar sign'); case self::FORMAT_TYPE_F: - return ['F', 'F (default numeric) format']; + return array('F', 'F (default numeric) format'); case self::FORMAT_TYPE_IB: - return ['IB', 'Integer binary']; + return array('IB', 'Integer binary'); case self::FORMAT_TYPE_PIBHEX: - return ['PIBHEX', 'Positive binary integer - hexadecimal']; + return array('PIBHEX', 'Positive binary integer - hexadecimal'); case self::FORMAT_TYPE_P: - return ['P', 'Packed decimal']; + return array('P', 'Packed decimal'); case self::FORMAT_TYPE_PIB: - return ['PIB', 'Positive integer binary (Unsigned)']; + return array('PIB', 'Positive integer binary (Unsigned)'); case self::FORMAT_TYPE_PK: - return ['PK', 'Positive packed decimal (Unsigned)']; + return array('PK', 'Positive packed decimal (Unsigned)'); case self::FORMAT_TYPE_RB: - return ['RB', 'Floating point binary']; + return array('RB', 'Floating point binary'); case self::FORMAT_TYPE_RBHEX: - return ['RBHEX', 'Floating point binary - hexadecimal']; + return array('RBHEX', 'Floating point binary - hexadecimal'); case self::FORMAT_TYPE_Z: - return ['Z', 'Zoned decimal']; + return array('Z', 'Zoned decimal'); case self::FORMAT_TYPE_N: - return ['N', 'N format - unsigned with leading zeros']; + return array('N', 'N format - unsigned with leading zeros'); case self::FORMAT_TYPE_E: - return ['E', 'E format - with explicit power of ten']; + return array('E', 'E format - with explicit power of ten'); case self::FORMAT_TYPE_DATE: - return ['DATE', 'Date format dd-mmm-yyyy']; + return array('DATE', 'Date format dd-mmm-yyyy'); case self::FORMAT_TYPE_TIME: - return ['TIME', 'Time format hh:mm:ss.s']; + return array('TIME', 'Time format hh:mm:ss.s'); case self::FORMAT_TYPE_DATETIME: - return ['DATETIME', 'Date and time']; + return array('DATETIME', 'Date and time'); case self::FORMAT_TYPE_ADATE: - return ['ADATE', 'Date in mm/dd/yyyy form']; + return array('ADATE', 'Date in mm/dd/yyyy form'); case self::FORMAT_TYPE_JDATE: - return ['JDATE', 'Julian date - yyyyddd']; + return array('JDATE', 'Julian date - yyyyddd'); case self::FORMAT_TYPE_DTIME: - return ['DTIME', 'Date-time dd hh:mm:ss.s']; + return array('DTIME', 'Date-time dd hh:mm:ss.s'); case self::FORMAT_TYPE_WKDAY: - return ['WKDAY', 'Day of the week']; + return array('WKDAY', 'Day of the week'); case self::FORMAT_TYPE_MONTH: - return ['MONTH', 'Month']; + return array('MONTH', 'Month'); case self::FORMAT_TYPE_MOYR: - return ['MOYR', 'mmm yyyy']; + return array('MOYR', 'mmm yyyy'); case self::FORMAT_TYPE_QYR: - return ['QYR', 'q Q yyyy']; + return array('QYR', 'q Q yyyy'); case self::FORMAT_TYPE_WKYR: - return ['WKYR', 'ww WK yyyy']; + return array('WKYR', 'ww WK yyyy'); case self::FORMAT_TYPE_PCT: - return ['PCT', 'Percent - F followed by "%"']; + return array('PCT', 'Percent - F followed by "%"'); case self::FORMAT_TYPE_DOT: - return ['DOT', 'Like COMMA, switching dot for comma']; + return array('DOT', 'Like COMMA, switching dot for comma'); case self::FORMAT_TYPE_CCA: - return ['CCA', 'User-programmable currency format (1)']; + return array('CCA', 'User-programmable currency format (1)'); case self::FORMAT_TYPE_CCB: - return ['CCB', 'User-programmable currency format (2)']; + return array('CCB', 'User-programmable currency format (2)'); case self::FORMAT_TYPE_CCC: - return ['CCC', 'User-programmable currency format (3)']; + return array('CCC', 'User-programmable currency format (3)'); case self::FORMAT_TYPE_CCD: - return ['CCD', 'User-programmable currency format (4)']; + return array('CCD', 'User-programmable currency format (4)'); case self::FORMAT_TYPE_CCE: - return ['CCE', 'User-programmable currency format (5)']; + return array('CCE', 'User-programmable currency format (5)'); case self::FORMAT_TYPE_EDATE: - return ['EDATE', 'Date in dd.mm.yyyy style']; + return array('EDATE', 'Date in dd.mm.yyyy style'); case self::FORMAT_TYPE_SDATE: - return ['SDATE', 'Date in yyyy/mm/dd style']; + return array('SDATE', 'Date in yyyy/mm/dd style'); } - return [null, null]; + return array(null, null); } /** * @param int $alignment + * * @return string */ public static function alignmentToString($alignment) @@ -222,11 +225,11 @@ public static function alignmentToString($alignment) */ public function getMeasure() { - if ($this->measure !== null) { + if (null !== $this->measure) { return $this->measure; } - return $this->width == 0 ? self::MEASURE_UNKNOWN : self::MEASURE_NOMINAL; + return 0 === $this->width ? self::MEASURE_UNKNOWN : self::MEASURE_NOMINAL; } /** @@ -234,11 +237,11 @@ public function getMeasure() */ public function getAlignment() { - if ($this->alignment !== null) { + if (null !== $this->alignment) { return $this->alignment; } - return $this->width == 0 ? self::ALIGN_RIGHT : self::ALIGN_LEFT; + return 0 === $this->width ? self::ALIGN_RIGHT : self::ALIGN_LEFT; } /** @@ -246,7 +249,7 @@ public function getAlignment() */ public function getColumns() { - if ($this->columns !== null) { + if (null !== $this->columns) { return $this->columns; } diff --git a/src/Sav/Writer.php b/src/Sav/Writer.php index aefbea9..65c9ffc 100644 --- a/src/Sav/Writer.php +++ b/src/Sav/Writer.php @@ -16,12 +16,12 @@ class Writer /** * @var Record\Variable[] */ - public $variables = []; + public $variables = array(); /** * @var Record\ValueLabel[] */ - public $valueLabels = []; + public $valueLabels = array(); /** * @var Record\Document @@ -31,7 +31,7 @@ class Writer /** * @var Record\Info[] */ - public $info = []; + public $info = array(); /** * @var Record\Data @@ -47,20 +47,22 @@ class Writer * Writer constructor. * * @param array $data + * * @throws \Exception */ - public function __construct($data = []) + public function __construct($data = array()) { $this->buffer = Buffer::factory(); $this->buffer->context = $this; - if (! empty($data)) { + if (!empty($data)) { $this->write($data); } } /** * @param array $data + * * @throws \Exception */ public function write($data) @@ -89,6 +91,7 @@ public function write($data) $this->info[Record\Info\VariableAttributes::SUBTYPE] = new Record\Info\VariableAttributes(); $this->info[Record\Info\LongStringValueLabels::SUBTYPE] = new Record\Info\LongStringValueLabels(); $this->info[Record\Info\LongStringMissingValues::SUBTYPE] = new Record\Info\LongStringMissingValues(); + $this->info[Record\Info\CharacterEncoding::SUBTYPE] = new Record\Info\CharacterEncoding('UTF-8'); $this->data = new Record\Data(); @@ -97,49 +100,46 @@ public function write($data) /** @var Variable $var */ // for ($idx = 0; $idx <= $variablesCount; $idx++) { foreach (array_values($data['variables']) as $idx => $var) { - - if (is_array($var)) { + if (\is_array($var)) { $var = new Variable($var); } - if (! preg_match('/^[A-Za-z0-9_]+$/', $var->name)) { - throw new \InvalidArgumentException( - sprintf('Variable name `%s` contains an illegal character.', $var->name) - ); + //if (! preg_match('/^[A-Za-z0-9_]+$/', $var->name)) { + // UTF-8 and '.' characters could pass here + if (!preg_match('/^[A-Za-z0-9_\.\x{4e00}-\x{9fa5}]+$/u', $var->name)) { + throw new \InvalidArgumentException(sprintf('Variable name `%s` contains an illegal character.', $var->name)); } if (empty($var->width)) { - throw new \InvalidArgumentException( - sprintf('Invalid field width. Should be an integer number greater than zero.') - ); + throw new \InvalidArgumentException(sprintf('Invalid field width. Should be an integer number greater than zero.')); } $variable = new Record\Variable(); - // TODO: refactory - $variable->name = 'V'.str_pad($idx + 1, 7, 0, STR_PAD_LEFT); + // TODO: refactory - keep 7 positions so we can add after that for 100 very long string segments + $variable->name = 'V' . str_pad($idx + 1, 5, 0, STR_PAD_LEFT); // $variable->name = strtoupper($var->name); // TODO: test - if ($var->format === Variable::FORMAT_TYPE_A) { + if (Variable::FORMAT_TYPE_A === $var->format) { $variable->width = $var->width; } else { $variable->width = 0; } $variable->label = $var->label; - $variable->print = [ + $variable->print = array( 0, $var->format, $var->width ? min($var->width, 255) : 8, $var->decimals, - ]; - $variable->write = [ + ); + $variable->write = array( 0, $var->format, $var->width ? min($var->width, 255) : 8, $var->decimals, - ]; + ); // TODO: refactory $shortName = $variable->name; @@ -151,9 +151,9 @@ public function write($data) if ($var->missing) { if ($var->width <= 8) { - if (count($var->missing) >= 3) { + if (\count($var->missing) >= 3) { $variable->missingValuesFormat = 3; - } elseif (count($var->missing) === 2) { + } elseif (2 === \count($var->missing)) { $variable->missingValuesFormat = -2; } else { $variable->missingValuesFormat = 1; @@ -168,20 +168,20 @@ public function write($data) if ($var->values) { if ($variable->width > 8) { - $this->info[Record\Info\LongStringValueLabels::SUBTYPE][$longName] = [ + $this->info[Record\Info\LongStringValueLabels::SUBTYPE][$longName] = array( 'width' => $var->width, 'values' => $var->values, - ]; + ); } else { - $valueLabel = new Record\ValueLabel([ + $valueLabel = new Record\ValueLabel(array( 'variables' => $this->variables, - ]); + )); foreach ($var->values as $key => $value) { - $valueLabel->labels[] = [ + $valueLabel->labels[] = array( 'value' => $key, 'label' => $value, - ]; - $valueLabel->indexes = [$nominalIdx + 1]; + ); + $valueLabel->indexes = array($nominalIdx + 1); } $this->valueLabels[] = $valueLabel; } @@ -194,16 +194,18 @@ public function write($data) } $segmentCount = Utils::widthToSegments($var->width); - for ($i = 0; $i < $segmentCount; $i++) { - $this->info[Record\Info\VariableDisplayParam::SUBTYPE][$idx] = [ + + for ($i = 0; $i < $segmentCount; ++$i) { + $this->info[Record\Info\VariableDisplayParam::SUBTYPE][] = array( $var->getMeasure(), $var->getColumns(), $var->getAlignment(), - ]; + ); } // TODO: refactory - $dataCount = count($var->data); + $dataCount = \count($var->data); + if ($dataCount > $this->header->casesCount) { $this->header->casesCount = $dataCount; } @@ -212,7 +214,7 @@ public function write($data) $this->data->matrix[$case][$idx] = $value; } - $nominalIdx += Utils::widthToOcts($variable->width); + $nominalIdx += Utils::widthToOcts($var->width); } $this->header->nominalCaseSize = $nominalIdx; @@ -231,10 +233,10 @@ public function write($data) } // write documents - if (! empty($data['documents'])) { - $this->document = new Record\Document([ + if (!empty($data['documents'])) { + $this->document = new Record\Document(array( 'lines' => $data['documents'], - ] + ) ); $this->document->write($this->buffer); } @@ -246,8 +248,27 @@ public function write($data) $this->data->write($this->buffer); } + /** + * @param $row + * + * @return void + */ + public function writeCase($row) + { + if (!isset($this->data)) { + $this->data = new Record\Data(); + } + + // update the header info about number of cases + $this->header->increaseCasesCount($this->buffer); + + // write data + $this->data->writeCase($this->buffer, $row); + } + /** * @param $file + * * @return false|int */ public function save($file) @@ -255,6 +276,18 @@ public function save($file) return $this->buffer->saveToFile($file); } + /** + * @return bool + */ + public function close() + { + if (isset($this->data)) { + $this->data->close(); + } + + return $this->buffer->close(); + } + /** * @return Buffer */ @@ -267,12 +300,14 @@ public function getBuffer() * @param string $className * @param array $data * @param string $group - * @return array + * * @throws Exception + * + * @return array */ private function prepareInfoRecord($className, $data, $group = 'info') { - if (! class_exists($className)) { + if (!class_exists($className)) { throw new Exception('Unknown class'); } $key = lcfirst(substr($className, strrpos($className, '\\') + 1)); @@ -280,7 +315,7 @@ private function prepareInfoRecord($className, $data, $group = 'info') return new $className( isset($data[$group]) && isset($data[$group][$key]) ? $data[$group][$key] : - [] + array() ); } } diff --git a/src/Utils.php b/src/Utils.php index dc064d1..63730f5 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -10,7 +10,8 @@ class Utils * SPSS represents a date as the number of seconds since the epoch, midnight, Oct. 14, 1582. * * @param $timestamp - * @param string $format + * @param string $format + * * @return false|int */ public static function formatDate($timestamp, $format = 'Y M d') @@ -21,8 +22,9 @@ public static function formatDate($timestamp, $format = 'Y M d') /** * Rounds X up to the next multiple of Y. * - * @param int $x - * @param int $y + * @param int $x + * @param int $y + * * @return int */ public static function roundUp($x, $y) @@ -33,8 +35,9 @@ public static function roundUp($x, $y) /** * Rounds X down to the prev multiple of Y. * - * @param int $x - * @param int $y + * @param int $x + * @param int $y + * * @return int */ public static function roundDown($x, $y) @@ -43,25 +46,25 @@ public static function roundDown($x, $y) } /** - * Convert bytes to string + * Convert bytes to string. * - * @param array $bytes * @return string */ public static function bytesToString(array $bytes) { $str = ''; foreach ($bytes as $byte) { - $str .= chr($byte); + $str .= \chr($byte); } return $str; } /** - * Convert double to string + * Convert double to string. + * + * @param float $num * - * @param double $num * @return string */ public static function doubleToString($num) @@ -70,8 +73,9 @@ public static function doubleToString($num) } /** - * @param string $str - * @return double + * @param string $str + * + * @return float */ public static function stringToDouble($str) { @@ -83,8 +87,8 @@ public static function stringToDouble($str) } /** - * @param array $bytes - * @param bool $unsigned + * @param bool $unsigned + * * @return int */ public static function bytesToInt(array $bytes, $unsigned = true) @@ -95,18 +99,19 @@ public static function bytesToInt(array $bytes, $unsigned = true) $value |= $b << $i * 8; } - return $unsigned ? $value : self::unsignedToSigned($value, count($bytes) * 8); + return $unsigned ? $value : self::unsignedToSigned($value, \count($bytes) * 8); } /** * @param $int - * @param int $size + * @param int $size + * * @return array */ public static function intToBytes($int, $size = 32) { $size = self::roundUp($size, 8); - $bytes = []; + $bytes = array(); for ($i = 0; $i < $size; $i += 8) { $bytes[] = 0xFF & $int >> $i; } @@ -116,8 +121,9 @@ public static function intToBytes($int, $size = 32) } /** - * @param int $value - * @param int $size + * @param int $value + * @param int $size + * * @return string */ public static function unsignedToSigned($value, $size = 32) @@ -131,8 +137,9 @@ public static function unsignedToSigned($value, $size = 32) } /** - * @param int $value - * @param int $size + * @param int $value + * @param int $size + * * @return string */ public static function signedToUnsigned($value, $size = 32) @@ -144,21 +151,22 @@ public static function signedToUnsigned($value, $size = 32) * Returns the number of bytes of uncompressed case data used for writing a variable of the given WIDTH to a system file. * All required space is included, including trailing padding and internal padding. * - * @param int $width + * @param int $width + * * @return int */ public static function widthToBytes($width) { // assert($width >= 0); - if ($width === 0) { + if (0 === $width) { $bytes = 8; - } elseif (! Variable::isVeryLong($width)) { + } elseif (!Variable::isVeryLong($width)) { $bytes = $width; } else { $chunks = $width / Variable::EFFECTIVE_VLS_CHUNK; $remainder = $width % Variable::EFFECTIVE_VLS_CHUNK; - $bytes = $remainder + ($chunks * self::roundUp(Variable::REAL_VLS_CHUNK, 8)); + $bytes = floor($chunks) * Variable::REAL_VLS_CHUNK + $remainder; } return self::roundUp($bytes, 8); @@ -167,20 +175,39 @@ public static function widthToBytes($width) /** * Returns the number of 8-byte units (octs) used to write data for a variable of the given WIDTH. * - * @param int $width + * @param int $width + * * @return int */ - public static function widthToOcts($width) + public static function widthToOctsOld($width) { return self::widthToBytes($width) / 8; } + /** + * Returns the number of 8-byte units (octs) used to write data for a variable of the given WIDTH. + * + * @param int $width + * + * @return int + */ + public static function widthToOcts($width) + { + $result = 0; + foreach (self::getSegments($width) as $segmentWidth) { + $result += ceil($segmentWidth / 8); + } + + return (int) max(1, $result); + } + /** * Returns the number of "segments" used for writing case data for a variable of the given WIDTH. * A segment is a physical variable in the system file that represents some piece of a logical variable. * Only very long string variables have more than one segment. * - * @param int $width + * @param int $width + * * @return int */ public static function widthToSegments($width) @@ -188,12 +215,27 @@ public static function widthToSegments($width) return Variable::isVeryLong($width) ? ceil($width / Variable::EFFECTIVE_VLS_CHUNK) : 1; } + /** + * @param $width + * + * @return \Generator + */ + public static function getSegments($width) + { + $count = self::widthToSegments($width); + for ($i = 1; $i < $count; ++$i) { + yield 255; + } + yield $width - ($count - 1) * Variable::EFFECTIVE_VLS_CHUNK; + } + /** * Returns the width to allocate to the given SEGMENT within a variable of the given WIDTH. * A segment is a physical variable in the system file that represents some piece of a logical variable. * - * @param int $width - * @param int $segment + * @param int $width + * @param int $segment + * * @return int */ public static function segmentAllocWidth($width, $segment = 0) @@ -201,7 +243,7 @@ public static function segmentAllocWidth($width, $segment = 0) $segmentCount = self::widthToSegments($width); // assert($segment < $segmentCount); - if (! Variable::isVeryLong($width)) { + if (!Variable::isVeryLong($width)) { return $width; } @@ -210,17 +252,19 @@ public static function segmentAllocWidth($width, $segment = 0) /** * Returns the number of bytes to allocate to the given SEGMENT within a variable of the given width. - * This is the same as @see segmentAllocWidth, except that a numeric value takes up 8 bytes despite having a width of 0. + * This is the same as. + * + * @param mixed $width + * @param int $segment * - * @param int $width - * @param int $segment * @return int + * + * @see segmentAllocWidth, except that a numeric value takes up 8 bytes despite having a width of 0. */ public static function segmentAllocBytes($width, $segment) { - assert($segment < self::widthToSegments($width)); + \assert($segment < self::widthToSegments($width)); - return $width === 0 ? 8 : self::roundUp(self::segmentAllocWidth($width, $segment), 8); + return 0 === $width ? 8 : self::roundUp(self::segmentAllocWidth($width, $segment), 8); } - } diff --git a/tests/LongStringTest.php b/tests/LongStringTest.php new file mode 100644 index 0000000..bb4d6bb --- /dev/null +++ b/tests/LongStringTest.php @@ -0,0 +1,72 @@ + array( + 'prodName' => '@(#) IBM SPSS STATISTICS', + 'layoutCode' => 2, + 'creationDate' => '08 May 19', + 'creationTime' => '12:22:16', + ), + 'variables' => array( + array( + 'name' => 'long', + 'label' => 'long label', + 'width' => 300, + 'format' => Variable::FORMAT_TYPE_A, + 'attributes' => array( + '$@Role' => Variable::ROLE_INPUT, + ), + 'data' => array( + $firstLong, + $secondLong, + ), + ), + array( + 'name' => 'short', + 'label' => 'short label', + 'format' => Variable::FORMAT_TYPE_A, + 'width' => 8, + 'attributes' => array( + '$@Role' => Variable::ROLE_INPUT, + ), + 'data' => array( + '12345678', + 'abcdefgh', + ), + ), + ), + ); + + /** @noinspection PhpUnhandledExceptionInspection */ + $writer = new Writer($data); + + // Uncomment if you want to really save and check the resulting file in SPSS + // $writer->save('longString.sav'); + + $buffer = $writer->getBuffer(); + $buffer->rewind(); + + $reader = Reader::fromString($buffer->getStream())->read(); + + $expected = array(); + $expected[0][0] = $data['variables'][0]['data'][0]; + $expected[0][1] = $data['variables'][1]['data'][0]; + $expected[1][0] = $data['variables'][0]['data'][1]; + $expected[1][1] = $data['variables'][1]['data'][1]; + + $this->assertEquals($expected, $reader->data); + } +} diff --git a/tests/MachineFloatingPointTest.php b/tests/MachineFloatingPointTest.php index 82dde4a..037ecda 100644 --- a/tests/MachineFloatingPointTest.php +++ b/tests/MachineFloatingPointTest.php @@ -9,36 +9,34 @@ class MachineFloatingPointTest extends TestCase { public function provider() { - return [ - [ - [ + return array( + array( + array( 'sysmis' => -1, 'highest' => 5, 'lowest' => -10, - ], - [ + ), + array( 'sysmis' => -1, 'highest' => 5, 'lowest' => -10, - ], - ], - [ - [], + ), + ), + array( + array(), // -1.7976931348623E+308 php min double // 1.7976931348623E+308 php max double - [ + array( 'sysmis' => -1.7976931348623158E+308, 'highest' => 1.7976931348623158E+308, 'lowest' => -1.7976931348623158E+308, - ], - ], - ]; + ), + ), + ); } /** * @dataProvider provider - * @param array $attributes - * @param array $expected */ public function testWriteRead(array $attributes, array $expected) { @@ -46,7 +44,7 @@ public function testWriteRead(array $attributes, array $expected) foreach ($attributes as $key => $value) { $subject->{$key} = $value; } - $buffer = Buffer::factory('', ['memory' => true]); + $buffer = Buffer::factory('', array('memory' => true)); $this->assertEquals(0, $buffer->position()); $subject->write($buffer); $buffer->rewind(); diff --git a/tests/SavDateFormatTest.php b/tests/SavDateFormatTest.php index 754e4eb..c97fcbd 100644 --- a/tests/SavDateFormatTest.php +++ b/tests/SavDateFormatTest.php @@ -2,9 +2,9 @@ namespace SPSS\Tests; +use SPSS\Sav\Reader; use SPSS\Sav\Record; use SPSS\Sav\Variable; -use SPSS\Sav\Reader; use SPSS\Sav\Writer; class SavDateFormatTest extends TestCase @@ -14,7 +14,7 @@ class SavDateFormatTest extends TestCase */ public function dataProvider() { - $header = [ + $header = array( 'recType' => Record\Header::NORMAL_REC_TYPE, 'prodName' => '@(#) SPSS DATA FILE', 'layoutCode' => 2, @@ -26,315 +26,317 @@ public function dataProvider() 'creationDate' => date('d M y'), 'creationTime' => date('H:i:s'), 'fileLabel' => 'test dates', - ]; + ); - $variables = [ - [ + $variables = array( + array( 'name' => 'DATE_11', 'format' => Variable::FORMAT_TYPE_DATE, // dd-mmm-yyyy 'width' => 11, - 'data' => [ + 'data' => array( '01-Jan-1001', '13-Feb-1989', '10-Jan-2017', - ], - ], - [ + ), + ), + array( 'name' => 'DATE_9', 'format' => Variable::FORMAT_TYPE_DATE, // dd-mmm-yy 'width' => 9, - 'data' => [ + 'data' => array( '01-Feb-89', '01-Feb-00', '01-Feb-17', - ], - ], - [ + ), + ), + array( 'name' => 'TIME_5', 'format' => Variable::FORMAT_TYPE_TIME, // hh:mm 'width' => 5, - 'data' => [ + 'data' => array( '00:00', '12:30', '59:59', - ], - ], - [ + ), + ), + array( 'name' => 'TIME_8', 'format' => Variable::FORMAT_TYPE_TIME, // hh:mm:ss 'width' => 8, - 'data' => [ + 'data' => array( '00:00:00', '12:30:13', '59:59:59', - ], - ], - [ + ), + ), + array( 'name' => 'TIME_11', 'format' => Variable::FORMAT_TYPE_TIME, // hh:mm:ss.s 'width' => 11, 'decimals' => 2, - 'data' => [ + 'data' => array( '00:00:00.12', '12:30:13.99', '59:59:59.99', - ], - ], - [ + ), + ), + array( 'name' => 'DTIME_17', 'format' => Variable::FORMAT_TYPE_DATETIME, // dd-mmm-yyy hh:mm 'width' => 17, - 'data' => [ + 'data' => array( '14-Oct-1989 13:30', '14-Oct-1989 13:30', '14-Oct-1989 13:30', - ], - ], - [ + ), + ), + array( 'name' => 'DTIME_20', 'format' => Variable::FORMAT_TYPE_DATETIME, // dd-mmm-yyy hh:mm:ss 'width' => 20, - 'data' => [ + 'data' => array( '13-Feb-1989 13:30:59', '13-Feb-1989 13:30:59', '13-Feb-1989 13:30:59', - ], - ], - [ + ), + ), + array( 'name' => 'DTIME_23', 'format' => Variable::FORMAT_TYPE_DATETIME, // dd-mmm-yyy hh:mm:ss 'width' => 23, 'decimals' => 2, - 'data' => [ + 'data' => array( '13-Feb-1989 13:30:59.99', '13-Feb-1989 13:30:59.99', '13-Feb-1989 13:30:59.99', - ], - ], - [ + ), + ), + array( 'name' => 'ADATE_8', 'format' => Variable::FORMAT_TYPE_ADATE, // mm/dd/yy 'width' => 8, - 'data' => [ + 'data' => array( '02/13/89', '02/13/89', '02/13/89', - ], - ], - [ + ), + ), + array( 'name' => 'ADATE_10', 'format' => Variable::FORMAT_TYPE_ADATE, // mm/dd/yyyy 'width' => 10, - 'data' => [ + 'data' => array( '02/13/1989', '02/13/1989', '02/13/1989', - ], - ], - [ + ), + ), + array( 'name' => 'JDATE_5', 'format' => Variable::FORMAT_TYPE_JDATE, // Julian date - yyddd 'width' => 5, - 'data' => [ + 'data' => array( '90301', '90301', '90301', - ], - ], - [ + ), + ), + array( 'name' => 'JDATE_7', 'format' => Variable::FORMAT_TYPE_JDATE, // Julian date - yyyyddd 'width' => 7, - 'data' => [ + 'data' => array( '1990301', '1990301', '1990301', - ], - ], - [ + ), + ), + array( 'name' => 'DTIME_9', 'format' => Variable::FORMAT_TYPE_DTIME, // dd hh:mm 'width' => 9, - 'data' => [ + 'data' => array( '13 13:13', '14 14:14', '15 15:15', - ], - ], - [ + ), + ), + array( 'name' => 'DTIME_12', 'format' => Variable::FORMAT_TYPE_DTIME, // dd hh:mm:ss 'width' => 12, - 'data' => [ + 'data' => array( '13 13:13:13', '14 14:14:14', '15 15:15:15', - ], - ], - [ + ), + ), + array( 'name' => 'DTIME_15', 'format' => Variable::FORMAT_TYPE_DTIME, // dd hh:mm:ss.s 'width' => 15, 'decimals' => 2, - 'data' => [ + 'data' => array( '13 13:13:13.13', '14 14:14:14.14', '15 15:15:15.15', - ], - ], - [ + ), + ), + array( 'name' => 'WKDAY', 'format' => Variable::FORMAT_TYPE_WKDAY, 'width' => 3, - 'data' => [ + 'data' => array( 'Sun', 'Mon', 'Tue', - ], - ], - [ + ), + ), + array( 'name' => 'WKDAY_9', 'format' => Variable::FORMAT_TYPE_WKDAY, // Monday 'width' => 9, - 'data' => [ + 'data' => array( 'Sunday', 'Monday', 'Tuesday', - ], - ], - [ + ), + ), + array( 'name' => 'MONTH', 'format' => Variable::FORMAT_TYPE_MONTH, // Jan 'width' => 3, - 'data' => [ + 'data' => array( 'Jan', 'Feb', 'Mar', - ], - ], - [ + ), + ), + array( 'name' => 'MONTH_9', 'format' => Variable::FORMAT_TYPE_MONTH, // January 'width' => 9, - 'data' => [ + 'data' => array( 'January', 'February', 'March', - ], - ], - [ + ), + ), + array( 'name' => 'MOYR_6', 'format' => Variable::FORMAT_TYPE_MOYR, // mmm yy 'width' => 6, - 'data' => [ + 'data' => array( 'OCT 90', 'OCT 90', 'OCT 90', - ], - ], - [ + ), + ), + array( 'name' => 'MOYR_8', 'format' => Variable::FORMAT_TYPE_MOYR, // mmm yyyy 'width' => 8, - 'data' => [ + 'data' => array( 'OCT 1990', 'OCT 1990', 'OCT 1990', - ], - ], - [ + ), + ), + array( 'name' => 'QYR_6', 'format' => Variable::FORMAT_TYPE_QYR, // q Q yy 'width' => 6, - 'data' => [ + 'data' => array( '4 Q 90', '4 Q 90', '4 Q 90', - ], - ], - [ + ), + ), + array( 'name' => 'QYR_8', 'format' => Variable::FORMAT_TYPE_QYR, // q Q yyyy 'width' => 8, - 'data' => [ + 'data' => array( '4 Q 1990', '4 Q 1990', '4 Q 1990', - ], - ], - [ + ), + ), + array( 'name' => 'WKYR_8', 'format' => Variable::FORMAT_TYPE_WKYR, // ww WK yy 'width' => 8, - 'data' => [ + 'data' => array( '43 WK 90', '43 WK 90', '43 WK 90', - ], - ], - [ + ), + ), + array( 'name' => 'WKYR_10', 'format' => Variable::FORMAT_TYPE_WKYR, // ww WK yyyy 'width' => 10, - 'data' => [ + 'data' => array( '43 WK 1990', '43 WK 1990', '43 WK 1990', - ], - ], - [ + ), + ), + array( 'name' => 'EDATE_8', 'format' => Variable::FORMAT_TYPE_EDATE, // dd.mm.yy 'width' => 8, - 'data' => [ + 'data' => array( '28.10.90', '28.10.90', '28.10.90', - ], - ], - [ + ), + ), + array( 'name' => 'EDATE_10', 'format' => Variable::FORMAT_TYPE_EDATE, // dd.mm.yyyy 'width' => 10, - 'data' => [ + 'data' => array( '28.10.1990', '28.10.1990', '28.10.1990', - ], - ], - [ + ), + ), + array( 'name' => 'SDATE_8', 'format' => Variable::FORMAT_TYPE_SDATE, // yy/mm/dd 'width' => 8, - 'data' => [ + 'data' => array( '90/10/28', '90/10/28', '90/10/28', - ], - ], - [ + ), + ), + array( 'name' => 'SDATE_10', 'format' => Variable::FORMAT_TYPE_SDATE, // yyyy/mm/dd 'width' => 10, - 'data' => [ + 'data' => array( '1990/10/28', '1990/10/28', '1990/10/28', - ], - ], - ]; + ), + ), + ); - return [ - [ + return array( + array( compact('header', 'variables'), - ], - ]; + ), + ); } /** * @dataProvider dataProvider + * * @param array $data - * @throws \Exception + * + * @throws \Throwable */ public function testWriteRead($data) { @@ -360,8 +362,7 @@ public function testWriteRead($data) $this->assertEquals($var['format'], $_var->print[1]); $this->assertEquals($var['width'], $_var->print[2]); - $index++; + ++$index; } } - } diff --git a/tests/SavRandomReadWriteTest.php b/tests/SavRandomReadWriteTest.php index 00c41fc..15fd0ba 100644 --- a/tests/SavRandomReadWriteTest.php +++ b/tests/SavRandomReadWriteTest.php @@ -11,68 +11,64 @@ class SavRandomReadWriteTest extends TestCase { public function provider() { - $header = [ + $header = array( 'recType' => Record\Header::NORMAL_REC_TYPE, 'prodName' => '@(#) SPSS DATA FILE', 'layoutCode' => 2, 'nominalCaseSize' => 0, - 'casesCount' => 1, // mt_rand(10, 100), + 'casesCount' => mt_rand(10, 100), 'compression' => 1, 'weightIndex' => 0, 'bias' => 100, 'creationDate' => date('d M y'), 'creationTime' => date('H:i:s'), 'fileLabel' => 'test read/write', - ]; + ); - $documents = [ + $documents = array( $this->generateRandomString(mt_rand(5, Record\Document::LENGTH)), $this->generateRandomString(mt_rand(5, Record\Document::LENGTH)), - ]; + ); - $variables = []; + $variables = array(); // Generate random variables $count = 1; // mt_rand(1, 20); - for ($i = 0; $i < $count; $i++) { - $var = $this->generateVariable([ + for ($i = 0; $i < $count; ++$i) { + $var = $this->generateVariable(array( 'id' => $this->generateRandomString(mt_rand(2, 100)), 'casesCount' => $header['casesCount'], - ] + ) ); $header['nominalCaseSize'] += Utils::widthToOcts($var['width']); $variables[] = $var; } - yield [compact('header', 'variables', 'documents')]; - - // $header['casesCount'] = 5; - // for ($i = 0; $i < 1000; $i++) { - // $variable = $this->generateVariable([ - // 'id' => $this->generateRandomString(mt_rand(2, 100)), - // 'casesCount' => $header['casesCount'], - // ]); - // $header['nominalCaseSize'] = Utils::widthToOcts($variable['width']); - // yield [ - // [ - // 'header' => $header, - // 'variables' => [$variable], - // 'documents' => $documents, - // ], - // ]; - // } - - // return [ - // [ - // compact('header', 'variables', 'documents'), - // ], - // ]; + yield array(compact('header', 'variables', 'documents')); + + $header['casesCount'] = 5; + for ($i = 0; $i < 100; ++$i) { + $variable = $this->generateVariable(array( + 'id' => $this->generateRandomString(mt_rand(2, 100)), + 'casesCount' => $header['casesCount'], + )); + $header['nominalCaseSize'] = Utils::widthToOcts($variable['width']); + yield array( + array( + 'header' => $header, + 'variables' => array($variable), + 'documents' => $documents, + ), + ); + } } /** * @dataProvider provider + * * @param array $data + * * @throws \Exception */ public function testWriteRead($data) @@ -95,7 +91,7 @@ public function testWriteRead($data) if (isset($reader->info[Record\Info\VeryLongString::SUBTYPE])) { $veryLongStrings = $reader->info[Record\Info\VeryLongString::SUBTYPE]->toArray(); } else { - $veryLongStrings = []; + $veryLongStrings = array(); } $index = 0; @@ -109,6 +105,7 @@ public function testWriteRead($data) $this->assertEquals($var['decimals'], $readVariable->print[3]); // Check variable data + foreach ($var['data'] as $case => $value) { $this->assertEquals($value, $reader->data[$case][$index]); } @@ -120,5 +117,4 @@ public function testWriteRead($data) // TODO: valueLabels // TODO: info } - } diff --git a/tests/TestCase.php b/tests/TestCase.php index e411b1d..24a175c 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -7,10 +7,6 @@ class TestCase extends \PHPUnit\Framework\TestCase { - /** - * @param array $header - * @param Reader $reader - */ protected function checkHeader(array $header, Reader $reader) { foreach ($header as $key => $value) { @@ -28,39 +24,40 @@ protected function checkHeader(array $header, Reader $reader) /** * @param array $opts + * * @return array */ - protected function generateVariable($opts = []) + protected function generateVariable($opts = array()) { - $opts = array_merge([ + $opts = array_merge(array( 'id' => uniqid('', true), 'numeric' => mt_rand(0, 1), 'casesCount' => 0, - ], $opts + ), $opts ); - $var = [ + $var = array( 'name' => sprintf('VAR%s', $opts['id']), 'label' => sprintf('Label (%s)', $opts['id']), 'columns' => mt_rand(0, 100), 'alignment' => mt_rand(0, 2), 'measure' => mt_rand(1, 3), 'width' => 8, - ]; + ); if ($opts['numeric']) { $var['format'] = Variable::FORMAT_TYPE_F; $var['decimals'] = mt_rand(0, 2); - for ($c = 0; $c < $opts['casesCount']; $c++) { + for ($c = 0; $c < $opts['casesCount']; ++$c) { $var['data'][$c] = mt_rand(1, 99999) . '.' . mt_rand(1, 99999); } } else { $var['format'] = Variable::FORMAT_TYPE_A; // TODO: test > 255 - $var['width'] = mt_rand(2, 500); + $var['width'] = mt_rand(2, 2000); $var['decimals'] = 0; - for ($c = 0; $c < $opts['casesCount']; $c++) { + for ($c = 0; $c < $opts['casesCount']; ++$c) { $var['data'][$c] = trim($this->generateRandomString(mt_rand(0, $var['width']))); } } @@ -70,14 +67,15 @@ protected function generateVariable($opts = []) /** * @param int $length + * * @return string */ protected function generateRandomString($length = 10) { $characters = '_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $charactersLength = strlen($characters); + $charactersLength = \strlen($characters); $randomString = ''; - for ($i = 0; $i < $length; $i++) { + for ($i = 0; $i < $length; ++$i) { $randomString .= $characters[mt_rand(0, $charactersLength - 1)]; } diff --git a/tests/WriteMultibyteTest.php b/tests/WriteMultibyteTest.php new file mode 100644 index 0000000..3ac17f9 --- /dev/null +++ b/tests/WriteMultibyteTest.php @@ -0,0 +1,126 @@ + array( + 'prodName' => '@(#) IBM SPSS STATISTICS', + 'layoutCode' => 2, + 'creationDate' => date('d M y'), + 'creationTime' => date('H:i:s'), + ), + 'variables' => array( + array( + 'name' => 'longname_longerthanexpected', + 'label' => 'Data zákończenia', + 'width' => 16, + 'format' => 1, + ), + array( + 'name' => 'ccc', + 'label' => 'áá345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901233á', + 'format' => 5, + 'values' => array( + 1 => 'áá345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901233á', + ), + ), + ), + ); + $writer = new Writer($data); + + $buffer = $writer->getBuffer(); + $buffer->rewind(); + + $reader = Reader::fromString($buffer->getStream())->read(); + + // Short variable label + $this->assertEquals($data['variables'][0]['label'], $reader->variables[0]->label); + + // Long variable label + $this->assertEquals(mb_substr($data['variables'][1]['values'][1], 0, -2, 'UTF-8'), + $reader->variables[1]->label); + + // Long value label + $this->assertEquals(mb_substr($data['variables'][1]['label'], 0, -2, 'UTF-8'), + $reader->valueLabels[0]->labels[0]['label']); + } + + /** + * ISSUE #20. + * + * Chinese value labels seem to work fine, but free text does not work + */ + public function testChinese() + { + $input = array( + 'header' => array( + 'prodName' => '@(#) IBM SPSS STATISTICS 64-bit Macintosh 23.0.0.0', + 'creationDate' => '05 Oct 18', + 'creationTime' => '01:36:53', + 'weightIndex' => 0, + ), + 'variables' => array( + array( + 'name' => 'test1', + 'format' => Variable::FORMAT_TYPE_F, + 'width' => 4, + 'decimals' => 2, + 'label' => 'test', + 'values' => array( + 1 => '1测试中文标签1', + 2 => '2测试中文标签2', + ), + 'missing' => array(), + 'columns' => 5, + 'alignment' => Variable::ALIGN_RIGHT, + 'measure' => Variable::MEASURE_SCALE, + 'attributes' => array( + '$@Role' => Variable::ROLE_PARTITION, + ), + 'data' => array(1, 1, 1), + ), + array( + 'name' => 'test2', + 'format' => Variable::FORMAT_TYPE_A, + 'width' => 100, + 'label' => 'test', + 'columns' => 100, + 'alignment' => Variable::ALIGN_LEFT, + 'measure' => Variable::MEASURE_NOMINAL, + 'attributes' => array( + '$@Role' => Variable::ROLE_SPLIT, + ), + 'data' => array( + '测试中文数据1', + '测试中文数据2', + '测试中文数据3', + ), + ), + ), + ); + + $writer = new Writer($input); + + // Uncomment if you want to really save and check the resulting file in SPSS + //$writer->save('chinese1.sav'); + $buffer = $writer->getBuffer(); + $buffer->rewind(); + + $reader = Reader::fromString($buffer->getStream())->read(); + $expected[0][0] = $input['variables'][0]['data'][0]; + $expected[0][1] = $input['variables'][1]['data'][0]; + $expected[1][0] = $input['variables'][0]['data'][1]; + $expected[1][1] = $input['variables'][1]['data'][1]; + $expected[2][0] = $input['variables'][0]['data'][2]; + $expected[2][1] = $input['variables'][1]['data'][2]; + $this->assertEquals($expected, $reader->data); + } +}