diff --git a/.travis.yml b/.travis.yml
index 6b870366..962786eb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,12 +5,27 @@ matrix:
env: PREFER_LOWEST=""
- php: 7.1
env: PREFER_LOWEST=""
-# - php: 7.1
-# env: PREFER_LOWEST="--prefer-lowest"
+
+cache:
+ directories:
+ - doc/doc-en
+ - vendor
+ - $HOME/.composer
before_script:
-- composer update $PREFER_LOWEST --no-interaction
+- composer install --no-interaction
- mkdir -p build/logs
+- |
+ if [ ! -d "doc/doc-en/en" ]; then
+ cd doc
+ svn co https://svn.php.net/repository/phpdoc/modules/doc-en doc-en
+ cd ..
+ else
+ cd doc/doc-en
+ svn update
+ cd ../..
+ fi
+
script:
- "./vendor/bin/phpunit"
#- "./vendor/bin/composer-require-checker --config-file=composer-require-checker.json"
diff --git a/composer.json b/composer.json
index d6410702..e1a9aaa2 100644
--- a/composer.json
+++ b/composer.json
@@ -1,21 +1,32 @@
{
- "name": "Julien",
+ "name": "thecodingmachine/safe",
"description": "Create a list of functional PHP functions which return false on error",
"autoload": {
+ "psr-4": {
+ "Safe\\": ["lib/", "generated/"]
+ }
+ },
+ "autoload-dev": {
"psr-4": {
"Safe\\": "src/"
}
},
"require-dev": {
"php": ">=7.1",
+ "ext-simplexml": "*",
"phpunit/phpunit": "^7",
"phpstan/phpstan": "^0.10.2",
"thecodingmachine/phpstan-strict-rules": "^0.10",
"phpoffice/phpspreadsheet": "^1.4",
- "ext-json": "^1.5"
+ "ext-json": "^1.5",
+ "symfony/console": "^4.1.4",
+ "squizlabs/php_codesniffer": "^3.2",
+ "php-coveralls/php-coveralls": "^2.1"
},
"scripts": {
- "phpstan": "phpstan analyse src -c phpstan.neon --level=7 --no-progress -vvv"
+ "phpstan": "phpstan analyse src -c phpstan.neon --level=7 --no-progress -vvv",
+ "cs-fix": "phpcbf",
+ "cs-check": "phpcs"
},
"require": {
}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 00000000..6ab48e8e
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,3357 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "33d3dc0aab22ea86384a160e88b47029",
+ "packages": [],
+ "packages-dev": [
+ {
+ "name": "composer/xdebug-handler",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/xdebug-handler.git",
+ "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/b8e9745fb9b06ea6664d8872c4505fb16df4611c",
+ "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0",
+ "psr/log": "^1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Composer\\XdebugHandler\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "John Stevenson",
+ "email": "john-stevenson@blueyonder.co.uk"
+ }
+ ],
+ "description": "Restarts a process without xdebug.",
+ "keywords": [
+ "Xdebug",
+ "performance"
+ ],
+ "time": "2018-08-31T19:07:57+00:00"
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "^6.2.3",
+ "squizlabs/php_codesniffer": "^3.0.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "time": "2017-07-22T11:58:36+00:00"
+ },
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "6.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
+ "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/promises": "^1.0",
+ "guzzlehttp/psr7": "^1.4",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "ext-curl": "*",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
+ "psr/log": "^1.0"
+ },
+ "suggest": {
+ "psr/log": "Required for using the Log middleware"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.3-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "time": "2018-04-22T15:46:56+00:00"
+ },
+ {
+ "name": "guzzlehttp/promises",
+ "version": "v1.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle promises library",
+ "keywords": [
+ "promise"
+ ],
+ "time": "2016-12-20T10:07:11+00:00"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "1.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
+ "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "time": "2017-03-20T17:10:46+00:00"
+ },
+ {
+ "name": "jean85/pretty-package-versions",
+ "version": "1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Jean85/pretty-package-versions.git",
+ "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48",
+ "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48",
+ "shasum": ""
+ },
+ "require": {
+ "ocramius/package-versions": "^1.2.0",
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Jean85\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Alessandro Lai",
+ "email": "alessandro.lai85@gmail.com"
+ }
+ ],
+ "description": "A wrapper for ocramius/package-versions to get pretty versions strings",
+ "keywords": [
+ "composer",
+ "package",
+ "release",
+ "versions"
+ ],
+ "time": "2018-06-13T13:22:40+00:00"
+ },
+ {
+ "name": "markbaker/complex",
+ "version": "1.4.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/MarkBaker/PHPComplex.git",
+ "reference": "a78d82ae4e682c3809fc3023d1b0ce654f6ab12b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/a78d82ae4e682c3809fc3023d1b0ce654f6ab12b",
+ "reference": "a78d82ae4e682c3809fc3023d1b0ce654f6ab12b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6.0|^7.0.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3",
+ "phpcompatibility/php-compatibility": "^8.0",
+ "phpdocumentor/phpdocumentor": "2.*",
+ "phploc/phploc": "2.*",
+ "phpmd/phpmd": "2.*",
+ "phpunit/phpunit": "^4.8.35|^5.4.0",
+ "sebastian/phpcpd": "2.*",
+ "squizlabs/php_codesniffer": "^3.3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Complex\\": "classes/src/"
+ },
+ "files": [
+ "classes/src/functions/abs.php",
+ "classes/src/functions/acos.php",
+ "classes/src/functions/acosh.php",
+ "classes/src/functions/acot.php",
+ "classes/src/functions/acoth.php",
+ "classes/src/functions/acsc.php",
+ "classes/src/functions/acsch.php",
+ "classes/src/functions/argument.php",
+ "classes/src/functions/asec.php",
+ "classes/src/functions/asech.php",
+ "classes/src/functions/asin.php",
+ "classes/src/functions/asinh.php",
+ "classes/src/functions/atan.php",
+ "classes/src/functions/atanh.php",
+ "classes/src/functions/conjugate.php",
+ "classes/src/functions/cos.php",
+ "classes/src/functions/cosh.php",
+ "classes/src/functions/cot.php",
+ "classes/src/functions/coth.php",
+ "classes/src/functions/csc.php",
+ "classes/src/functions/csch.php",
+ "classes/src/functions/exp.php",
+ "classes/src/functions/inverse.php",
+ "classes/src/functions/ln.php",
+ "classes/src/functions/log2.php",
+ "classes/src/functions/log10.php",
+ "classes/src/functions/negative.php",
+ "classes/src/functions/pow.php",
+ "classes/src/functions/rho.php",
+ "classes/src/functions/sec.php",
+ "classes/src/functions/sech.php",
+ "classes/src/functions/sin.php",
+ "classes/src/functions/sinh.php",
+ "classes/src/functions/sqrt.php",
+ "classes/src/functions/tan.php",
+ "classes/src/functions/tanh.php",
+ "classes/src/functions/theta.php",
+ "classes/src/operations/add.php",
+ "classes/src/operations/subtract.php",
+ "classes/src/operations/multiply.php",
+ "classes/src/operations/divideby.php",
+ "classes/src/operations/divideinto.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mark Baker",
+ "email": "mark@lange.demon.co.uk"
+ }
+ ],
+ "description": "PHP Class for working with complex numbers",
+ "homepage": "https://github.com/MarkBaker/PHPComplex",
+ "keywords": [
+ "complex",
+ "mathematics"
+ ],
+ "time": "2018-07-31T08:38:40+00:00"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
+ "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
+ "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": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "time": "2018-06-11T23:09:50+00:00"
+ },
+ {
+ "name": "nette/bootstrap",
+ "version": "v2.4.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nette/bootstrap.git",
+ "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nette/bootstrap/zipball/268816e3f1bb7426c3a4ceec2bd38a036b532543",
+ "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543",
+ "shasum": ""
+ },
+ "require": {
+ "nette/di": "~2.4.7",
+ "nette/utils": "~2.4",
+ "php": ">=5.6.0"
+ },
+ "conflict": {
+ "nette/nette": "<2.2"
+ },
+ "require-dev": {
+ "latte/latte": "~2.2",
+ "nette/application": "~2.3",
+ "nette/caching": "~2.3",
+ "nette/database": "~2.3",
+ "nette/forms": "~2.3",
+ "nette/http": "~2.4.0",
+ "nette/mail": "~2.3",
+ "nette/robot-loader": "^2.4.2 || ^3.0",
+ "nette/safe-stream": "~2.2",
+ "nette/security": "~2.3",
+ "nette/tester": "~2.0",
+ "tracy/tracy": "^2.4.1"
+ },
+ "suggest": {
+ "nette/robot-loader": "to use Configurator::createRobotLoader()",
+ "tracy/tracy": "to use Configurator::enableTracy()"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause",
+ "GPL-2.0",
+ "GPL-3.0"
+ ],
+ "authors": [
+ {
+ "name": "David Grudl",
+ "homepage": "https://davidgrudl.com"
+ },
+ {
+ "name": "Nette Community",
+ "homepage": "https://nette.org/contributors"
+ }
+ ],
+ "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.",
+ "homepage": "https://nette.org",
+ "keywords": [
+ "bootstrapping",
+ "configurator",
+ "nette"
+ ],
+ "time": "2018-05-17T12:52:20+00:00"
+ },
+ {
+ "name": "nette/di",
+ "version": "v2.4.13",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nette/di.git",
+ "reference": "3f8f212b02d5c17feb97a7e0a39ab306f40c06ca"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nette/di/zipball/3f8f212b02d5c17feb97a7e0a39ab306f40c06ca",
+ "reference": "3f8f212b02d5c17feb97a7e0a39ab306f40c06ca",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "nette/neon": "^2.3.3 || ~3.0.0",
+ "nette/php-generator": "^2.6.1 || ~3.0.0",
+ "nette/utils": "^2.4.3 || ~3.0.0",
+ "php": ">=5.6.0"
+ },
+ "conflict": {
+ "nette/bootstrap": "<2.4",
+ "nette/nette": "<2.2"
+ },
+ "require-dev": {
+ "nette/tester": "^2.0",
+ "tracy/tracy": "^2.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause",
+ "GPL-2.0",
+ "GPL-3.0"
+ ],
+ "authors": [
+ {
+ "name": "David Grudl",
+ "homepage": "https://davidgrudl.com"
+ },
+ {
+ "name": "Nette Community",
+ "homepage": "https://nette.org/contributors"
+ }
+ ],
+ "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.",
+ "homepage": "https://nette.org",
+ "keywords": [
+ "compiled",
+ "di",
+ "dic",
+ "factory",
+ "ioc",
+ "nette",
+ "static"
+ ],
+ "time": "2018-06-11T08:46:01+00:00"
+ },
+ {
+ "name": "nette/finder",
+ "version": "v2.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nette/finder.git",
+ "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nette/finder/zipball/ee951a656cb8ac622e5dd33474a01fd2470505a0",
+ "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0",
+ "shasum": ""
+ },
+ "require": {
+ "nette/utils": "~2.4",
+ "php": ">=5.6.0"
+ },
+ "conflict": {
+ "nette/nette": "<2.2"
+ },
+ "require-dev": {
+ "nette/tester": "~2.0",
+ "tracy/tracy": "^2.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause",
+ "GPL-2.0",
+ "GPL-3.0"
+ ],
+ "authors": [
+ {
+ "name": "David Grudl",
+ "homepage": "https://davidgrudl.com"
+ },
+ {
+ "name": "Nette Community",
+ "homepage": "https://nette.org/contributors"
+ }
+ ],
+ "description": "🔍 Nette Finder: find files and directories with an intuitive API.",
+ "homepage": "https://nette.org",
+ "keywords": [
+ "filesystem",
+ "glob",
+ "iterator",
+ "nette"
+ ],
+ "time": "2018-06-28T11:49:23+00:00"
+ },
+ {
+ "name": "nette/neon",
+ "version": "v2.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nette/neon.git",
+ "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nette/neon/zipball/5e72b1dd3e2d34f0863c5561139a19df6a1ef398",
+ "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398",
+ "shasum": ""
+ },
+ "require": {
+ "ext-iconv": "*",
+ "ext-json": "*",
+ "php": ">=5.6.0"
+ },
+ "require-dev": {
+ "nette/tester": "~2.0",
+ "tracy/tracy": "^2.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause",
+ "GPL-2.0",
+ "GPL-3.0"
+ ],
+ "authors": [
+ {
+ "name": "David Grudl",
+ "homepage": "https://davidgrudl.com"
+ },
+ {
+ "name": "Nette Community",
+ "homepage": "https://nette.org/contributors"
+ }
+ ],
+ "description": "🍸 Nette NEON: encodes and decodes NEON file format.",
+ "homepage": "http://ne-on.org",
+ "keywords": [
+ "export",
+ "import",
+ "neon",
+ "nette",
+ "yaml"
+ ],
+ "time": "2018-03-21T12:12:21+00:00"
+ },
+ {
+ "name": "nette/php-generator",
+ "version": "v3.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nette/php-generator.git",
+ "reference": "ea90209c2e8a7cd087b2742ca553c047a8df5eff"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nette/php-generator/zipball/ea90209c2e8a7cd087b2742ca553c047a8df5eff",
+ "reference": "ea90209c2e8a7cd087b2742ca553c047a8df5eff",
+ "shasum": ""
+ },
+ "require": {
+ "nette/utils": "^2.4.2 || ~3.0.0",
+ "php": ">=7.0"
+ },
+ "conflict": {
+ "nette/nette": "<2.2"
+ },
+ "require-dev": {
+ "nette/tester": "^2.0",
+ "tracy/tracy": "^2.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause",
+ "GPL-2.0",
+ "GPL-3.0"
+ ],
+ "authors": [
+ {
+ "name": "David Grudl",
+ "homepage": "https://davidgrudl.com"
+ },
+ {
+ "name": "Nette Community",
+ "homepage": "https://nette.org/contributors"
+ }
+ ],
+ "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.2 features.",
+ "homepage": "https://nette.org",
+ "keywords": [
+ "code",
+ "nette",
+ "php",
+ "scaffolding"
+ ],
+ "time": "2018-08-09T14:32:27+00:00"
+ },
+ {
+ "name": "nette/robot-loader",
+ "version": "v3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nette/robot-loader.git",
+ "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nette/robot-loader/zipball/fc76c70e740b10f091e502b2e393d0be912f38d4",
+ "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "nette/finder": "^2.3 || ^3.0",
+ "nette/utils": "^2.4 || ^3.0",
+ "php": ">=5.6.0"
+ },
+ "conflict": {
+ "nette/nette": "<2.2"
+ },
+ "require-dev": {
+ "nette/tester": "^2.0",
+ "tracy/tracy": "^2.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause",
+ "GPL-2.0",
+ "GPL-3.0"
+ ],
+ "authors": [
+ {
+ "name": "David Grudl",
+ "homepage": "https://davidgrudl.com"
+ },
+ {
+ "name": "Nette Community",
+ "homepage": "https://nette.org/contributors"
+ }
+ ],
+ "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.",
+ "homepage": "https://nette.org",
+ "keywords": [
+ "autoload",
+ "class",
+ "interface",
+ "nette",
+ "trait"
+ ],
+ "time": "2018-08-13T14:19:06+00:00"
+ },
+ {
+ "name": "nette/utils",
+ "version": "v2.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nette/utils.git",
+ "reference": "183069866dc477fcfbac393ed486aaa6d93d19a5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nette/utils/zipball/183069866dc477fcfbac393ed486aaa6d93d19a5",
+ "reference": "183069866dc477fcfbac393ed486aaa6d93d19a5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6.0"
+ },
+ "conflict": {
+ "nette/nette": "<2.2"
+ },
+ "require-dev": {
+ "nette/tester": "~2.0",
+ "tracy/tracy": "^2.3"
+ },
+ "suggest": {
+ "ext-gd": "to use Image",
+ "ext-iconv": "to use Strings::webalize() and toAscii()",
+ "ext-intl": "for script transliteration in Strings::webalize() and toAscii()",
+ "ext-json": "to use Nette\\Utils\\Json",
+ "ext-mbstring": "to use Strings::lower() etc...",
+ "ext-xml": "to use Strings::length() etc. when mbstring is not available"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.5-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ],
+ "files": [
+ "src/loader.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause",
+ "GPL-2.0",
+ "GPL-3.0"
+ ],
+ "authors": [
+ {
+ "name": "David Grudl",
+ "homepage": "https://davidgrudl.com"
+ },
+ {
+ "name": "Nette Community",
+ "homepage": "https://nette.org/contributors"
+ }
+ ],
+ "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": [
+ "array",
+ "core",
+ "datetime",
+ "images",
+ "json",
+ "nette",
+ "paginator",
+ "password",
+ "slugify",
+ "string",
+ "unicode",
+ "utf-8",
+ "utility",
+ "validation"
+ ],
+ "time": "2018-05-02T17:16:08+00:00"
+ },
+ {
+ "name": "nikic/php-parser",
+ "version": "v4.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "bd088dc940a418f09cda079a9b5c7c478890fb8d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bd088dc940a418f09cda079a9b5c7c478890fb8d",
+ "reference": "bd088dc940a418f09cda079a9b5c7c478890fb8d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.5 || ^7.0"
+ },
+ "bin": [
+ "bin/php-parse"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Nikita Popov"
+ }
+ ],
+ "description": "A PHP parser written in PHP",
+ "keywords": [
+ "parser",
+ "php"
+ ],
+ "time": "2018-07-15T17:25:16+00:00"
+ },
+ {
+ "name": "ocramius/package-versions",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Ocramius/PackageVersions.git",
+ "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f",
+ "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0.0",
+ "php": "^7.1.0"
+ },
+ "require-dev": {
+ "composer/composer": "^1.6.3",
+ "ext-zip": "*",
+ "infection/infection": "^0.7.1",
+ "phpunit/phpunit": "^7.0.0"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "PackageVersions\\Installer",
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PackageVersions\\": "src/PackageVersions"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com"
+ }
+ ],
+ "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
+ "time": "2018-02-05T13:05:30+00:00"
+ },
+ {
+ "name": "phar-io/manifest",
+ "version": "1.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/manifest.git",
+ "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+ "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-phar": "*",
+ "phar-io/version": "^2.0",
+ "php": "^5.6 || ^7.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": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+ "time": "2018-07-08T19:23:20+00:00"
+ },
+ {
+ "name": "phar-io/version",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/version.git",
+ "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+ "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Library for handling version information and constraints",
+ "time": "2018-07-08T19:19:57+00:00"
+ },
+ {
+ "name": "php-coveralls/php-coveralls",
+ "version": "v2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-coveralls/php-coveralls.git",
+ "reference": "3b00c229726f892bfdadeaf01ea430ffd04a939d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/3b00c229726f892bfdadeaf01ea430ffd04a939d",
+ "reference": "3b00c229726f892bfdadeaf01ea430ffd04a939d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-simplexml": "*",
+ "guzzlehttp/guzzle": "^6.0",
+ "php": "^5.5 || ^7.0",
+ "psr/log": "^1.0",
+ "symfony/config": "^2.1 || ^3.0 || ^4.0",
+ "symfony/console": "^2.1 || ^3.0 || ^4.0",
+ "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0",
+ "symfony/yaml": "^2.0 || ^3.0 || ^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0"
+ },
+ "suggest": {
+ "symfony/http-kernel": "Allows Symfony integration"
+ },
+ "bin": [
+ "bin/php-coveralls"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpCoveralls\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kitamura Satoshi",
+ "email": "with.no.parachute@gmail.com",
+ "homepage": "https://www.facebook.com/satooshi.jp",
+ "role": "Original creator"
+ },
+ {
+ "name": "Takashi Matsuo",
+ "email": "tmatsuo@google.com"
+ },
+ {
+ "name": "Google Inc"
+ },
+ {
+ "name": "Dariusz Ruminski",
+ "email": "dariusz.ruminski@gmail.com",
+ "homepage": "https://github.com/keradus"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/php-coveralls/php-coveralls/graphs/contributors"
+ }
+ ],
+ "description": "PHP client library for Coveralls API",
+ "homepage": "https://github.com/php-coveralls/php-coveralls",
+ "keywords": [
+ "ci",
+ "coverage",
+ "github",
+ "test"
+ ],
+ "time": "2018-05-22T23:11:08+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ],
+ "time": "2017-09-11T18:02:19+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "4.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "phpdocumentor/reflection-common": "^1.0.0",
+ "phpdocumentor/type-resolver": "^0.4.0",
+ "webmozart/assert": "^1.0"
+ },
+ "require-dev": {
+ "doctrine/instantiator": "~1.0.5",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "time": "2017-11-30T07:14:17+00:00"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "0.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^5.2||^4.8.24"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.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"
+ }
+ ],
+ "time": "2017-07-14T14:27:02+00:00"
+ },
+ {
+ "name": "phpoffice/phpspreadsheet",
+ "version": "1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
+ "reference": "125f462a718956f37d81305ca0df4f17cef0f3b9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/125f462a718956f37d81305ca0df4f17cef0f3b9",
+ "reference": "125f462a718956f37d81305ca0df4f17cef0f3b9",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-dom": "*",
+ "ext-gd": "*",
+ "ext-iconv": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-simplexml": "*",
+ "ext-xml": "*",
+ "ext-xmlreader": "*",
+ "ext-xmlwriter": "*",
+ "ext-zip": "*",
+ "ext-zlib": "*",
+ "markbaker/complex": "^1.4.1",
+ "php": "^5.6|^7.0",
+ "psr/simple-cache": "^1.0"
+ },
+ "require-dev": {
+ "dompdf/dompdf": "^0.8.0",
+ "friendsofphp/php-cs-fixer": "@stable",
+ "jpgraph/jpgraph": "^4.0",
+ "mpdf/mpdf": "^7.0.0",
+ "phpunit/phpunit": "^5.7",
+ "squizlabs/php_codesniffer": "^3.3",
+ "tecnickcom/tcpdf": "^6.2"
+ },
+ "suggest": {
+ "dompdf/dompdf": "Option for rendering PDF with PDF Writer",
+ "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
+ "mpdf/mpdf": "Option for rendering PDF with PDF Writer",
+ "tecnick.com/tcpdf": "Option for rendering PDF with PDF Writer"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Maarten Balliauw",
+ "homepage": "http://blog.maartenballiauw.be"
+ },
+ {
+ "name": "Erik Tilt"
+ },
+ {
+ "name": "Franck Lefevre",
+ "homepage": "http://rootslabs.net"
+ },
+ {
+ "name": "Mark Baker",
+ "homepage": "http://markbakeruk.net"
+ }
+ ],
+ "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
+ "homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
+ "keywords": [
+ "OpenXML",
+ "excel",
+ "gnumeric",
+ "ods",
+ "php",
+ "spreadsheet",
+ "xls",
+ "xlsx"
+ ],
+ "time": "2018-08-06T02:58:06+00:00"
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "1.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+ "sebastian/comparator": "^1.1|^2.0|^3.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.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.8.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+ "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": "2018-08-05T17:53:17+00:00"
+ },
+ {
+ "name": "phpstan/phpdoc-parser",
+ "version": "0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpdoc-parser.git",
+ "reference": "ed3223362174b8067729930439e139794e9e514a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/ed3223362174b8067729930439e139794e9e514a",
+ "reference": "ed3223362174b8067729930439e139794e9e514a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "~7.1"
+ },
+ "require-dev": {
+ "consistence/coding-standard": "^2.0.0",
+ "jakub-onderka/php-parallel-lint": "^0.9.2",
+ "phing/phing": "^2.16.0",
+ "phpstan/phpstan": "^0.10@dev",
+ "phpunit/phpunit": "^6.3",
+ "slevomat/coding-standard": "^3.3.0",
+ "symfony/process": "^3.4 || ^4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.3-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": "2018-06-20T17:48:01+00:00"
+ },
+ {
+ "name": "phpstan/phpstan",
+ "version": "0.10.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan.git",
+ "reference": "dc62f78c9aa6e9f7c44e8d6518f1123cd1e1b1c0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc62f78c9aa6e9f7c44e8d6518f1123cd1e1b1c0",
+ "reference": "dc62f78c9aa6e9f7c44e8d6518f1123cd1e1b1c0",
+ "shasum": ""
+ },
+ "require": {
+ "composer/xdebug-handler": "^1.0",
+ "jean85/pretty-package-versions": "^1.0.3",
+ "nette/bootstrap": "^2.4 || ^3.0",
+ "nette/di": "^2.4.7 || ^3.0",
+ "nette/robot-loader": "^3.0.1",
+ "nette/utils": "^2.4.5 || ^3.0",
+ "nikic/php-parser": "^4.0.2",
+ "php": "~7.1",
+ "phpstan/phpdoc-parser": "^0.3",
+ "symfony/console": "~3.2 || ~4.0",
+ "symfony/finder": "~3.2 || ~4.0"
+ },
+ "require-dev": {
+ "brianium/paratest": "^2.0",
+ "consistence/coding-standard": "^3.3",
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
+ "ext-gd": "*",
+ "ext-intl": "*",
+ "ext-mysqli": "*",
+ "ext-zip": "*",
+ "jakub-onderka/php-parallel-lint": "^1.0",
+ "localheinz/composer-normalize": "~0.8.0",
+ "phing/phing": "^2.16.0",
+ "phpstan/phpstan-deprecation-rules": "^0.10.2",
+ "phpstan/phpstan-php-parser": "^0.10",
+ "phpstan/phpstan-phpunit": "^0.10",
+ "phpstan/phpstan-strict-rules": "^0.10",
+ "phpunit/phpunit": "^7.0",
+ "slevomat/coding-standard": "^4.6.2"
+ },
+ "bin": [
+ "bin/phpstan"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.10-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\": [
+ "src/",
+ "build/PHPStan"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPStan - PHP Static Analysis Tool",
+ "time": "2018-08-12T15:14:21+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "6.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a",
+ "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.1",
+ "phpunit/php-file-iterator": "^2.0",
+ "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-06-01T07:51:50+00:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cecbc684605bb0cc288828eb5d65d93d5c676d3c",
+ "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "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": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "time": "2018-06-11T11:44:00+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.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f",
+ "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "time": "2018-02-01T13:07:23+00:00"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace",
+ "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "time": "2018-02-01T13:16:43+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "7.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "0356331bf62896dc56e3a15030b23b73f38b2935"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0356331bf62896dc56e3a15030b23b73f38b2935",
+ "reference": "0356331bf62896dc56e3a15030b23b73f38b2935",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.1",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "myclabs/deep-copy": "^1.7",
+ "phar-io/manifest": "^1.0.2",
+ "phar-io/version": "^2.0",
+ "php": "^7.1",
+ "phpspec/prophecy": "^1.7",
+ "phpunit/php-code-coverage": "^6.0.7",
+ "phpunit/php-file-iterator": "^2.0.1",
+ "phpunit/php-text-template": "^1.2.1",
+ "phpunit/php-timer": "^2.0",
+ "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"
+ },
+ "conflict": {
+ "phpunit/phpunit-mock-objects": "*"
+ },
+ "require-dev": {
+ "ext-pdo": "*"
+ },
+ "suggest": {
+ "ext-soap": "*",
+ "ext-xdebug": "*",
+ "phpunit/php-invoker": "^2.0"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.3-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-09-05T09:58:53+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "time": "2016-08-06T14:39:51+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.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": "2016-10-10T12:19:37+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": "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.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "366541b989927187c4ca70490a35615d3fef2dce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce",
+ "reference": "366541b989927187c4ca70490a35615d3fef2dce",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.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": "2018-06-10T07:54:39+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.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "234199f4528de6d12aaa58b612e98f7d36adb937"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937",
+ "reference": "234199f4528de6d12aaa58b612e98f7d36adb937",
+ "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": "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"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2017-04-03T13:19:02+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.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
+ "reference": "628a481780561150481a9ec74709092b9759b3ec"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/628a481780561150481a9ec74709092b9759b3ec",
+ "reference": "628a481780561150481a9ec74709092b9759b3ec",
+ "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": "http://www.squizlabs.com/php-codesniffer",
+ "keywords": [
+ "phpcs",
+ "standards"
+ ],
+ "time": "2018-07-26T23:47:18+00:00"
+ },
+ {
+ "name": "symfony/config",
+ "version": "v4.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/config.git",
+ "reference": "76015a3cc372b14d00040ff58e18e29f69eba717"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/config/zipball/76015a3cc372b14d00040ff58e18e29f69eba717",
+ "reference": "76015a3cc372b14d00040ff58e18e29f69eba717",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/filesystem": "~3.4|~4.0",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "conflict": {
+ "symfony/finder": "<3.4"
+ },
+ "require-dev": {
+ "symfony/dependency-injection": "~3.4|~4.0",
+ "symfony/event-dispatcher": "~3.4|~4.0",
+ "symfony/finder": "~3.4|~4.0",
+ "symfony/yaml": "~3.4|~4.0"
+ },
+ "suggest": {
+ "symfony/yaml": "To use the yaml reference dumper"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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",
+ "time": "2018-08-08T06:37:38+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v4.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/ca80b8ced97cf07390078b29773dc384c39eee1f",
+ "reference": "ca80b8ced97cf07390078b29773dc384c39eee1f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<3.4",
+ "symfony/process": "<3.3"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~3.4|~4.0",
+ "symfony/dependency-injection": "~3.4|~4.0",
+ "symfony/event-dispatcher": "~3.4|~4.0",
+ "symfony/lock": "~3.4|~4.0",
+ "symfony/process": "~3.4|~4.0"
+ },
+ "suggest": {
+ "psr/log-implementation": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/lock": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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",
+ "time": "2018-07-26T11:24:31+00:00"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v4.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e",
+ "reference": "c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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",
+ "time": "2018-08-18T16:52:46+00:00"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "v4.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/e162f1df3102d0b7472805a5a9d5db9fcf0a8068",
+ "reference": "e162f1df3102d0b7472805a5a9d5db9fcf0a8068",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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",
+ "time": "2018-07-26T11:24:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
+ "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ },
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "time": "2018-08-06T14:22:27+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8",
+ "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.9-dev"
+ }
+ },
+ "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"
+ ],
+ "time": "2018-08-06T14:22:27+00:00"
+ },
+ {
+ "name": "symfony/stopwatch",
+ "version": "v4.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/stopwatch.git",
+ "reference": "966c982df3cca41324253dc0c7ffe76b6076b705"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/966c982df3cca41324253dc0c7ffe76b6076b705",
+ "reference": "966c982df3cca41324253dc0c7ffe76b6076b705",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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",
+ "time": "2018-07-26T11:00:49+00:00"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v4.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "b832cc289608b6d305f62149df91529a2ab3c314"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/b832cc289608b6d305f62149df91529a2ab3c314",
+ "reference": "b832cc289608b6d305f62149df91529a2ab3c314",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "conflict": {
+ "symfony/console": "<3.4"
+ },
+ "require-dev": {
+ "symfony/console": "~3.4|~4.0"
+ },
+ "suggest": {
+ "symfony/console": "For validating YAML files using the lint command"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "https://symfony.com",
+ "time": "2018-08-18T16:52:46+00:00"
+ },
+ {
+ "name": "thecodingmachine/phpstan-strict-rules",
+ "version": "v0.10.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thecodingmachine/phpstan-strict-rules.git",
+ "reference": "4171d4426cd6289ae9231061aa0e39a09c6e3133"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thecodingmachine/phpstan-strict-rules/zipball/4171d4426cd6289ae9231061aa0e39a09c6e3133",
+ "reference": "4171d4426cd6289ae9231061aa0e39a09c6e3133",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1",
+ "phpstan/phpstan": "^0.10"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.10-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "TheCodingMachine\\PHPStan\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "David Négrier",
+ "email": "d.negrier@thecodingmachine.com"
+ }
+ ],
+ "description": "A set of additional rules for PHPStan based on best practices followed at TheCodingMachine",
+ "time": "2018-07-06T12:40:23+00:00"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b",
+ "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "time": "2017-04-07T12:08:54+00:00"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozart/assert.git",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6",
+ "sebastian/version": "^1.0.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ],
+ "time": "2018-01-29T19:49:41+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": {
+ "php": ">=7.1",
+ "ext-simplexml": "*",
+ "ext-json": "^1.5"
+ }
+}
diff --git a/doc/entities/.gitkeep b/doc/entities/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/generated/Exceptions/.gitkeep b/generated/Exceptions/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/generated/lib.php b/generated/lib.php
deleted file mode 100644
index 08a6a6cc..00000000
--- a/generated/lib.php
+++ /dev/null
@@ -1,15916 +0,0 @@
-addCommands([new GenerateCommand()]);
+
+$application->run();
diff --git a/src/DocPage.php b/src/DocPage.php
index c99fed30..85219ce1 100644
--- a/src/DocPage.php
+++ b/src/DocPage.php
@@ -13,7 +13,8 @@ class DocPage
* @return string
* @parameter string
*/
- public function __construct(string $_path) {
+ public function __construct(string $_path)
+ {
$this->path = $_path;
}
@@ -22,11 +23,15 @@ public function __construct(string $_path) {
*
* @return bool
*/
- public function detectFalsyFunction(): bool {
+ public function detectFalsyFunction(): bool
+ {
$file = file_get_contents($this->path);
if (!preg_match('/::/m', $file)) {
- if (preg_match('/&false; on error/m', $file)) {
+ if (preg_match('/&false;\s+on\s+error/m', $file)) {
+ return true;
+ }
+ if (preg_match('/&false;\s+if\s+an\s+error\s+occurred/m', $file)) {
return true;
}
if (preg_match('/&return.success;/m', $file)) {
@@ -38,54 +43,129 @@ public function detectFalsyFunction(): bool {
if (preg_match('/&return.falseforfailure;/m', $file)) {
return true;
}
- if (preg_match('/&return.falseproblem;/m', $file)) {
- return true;
- }
}
return false;
}
- /*
- * @return SimpleXMLElement[]
+ /**
+ * @return \SimpleXMLElement[]
*/
- public function getMethodSynopsis(): array {
+ public function getMethodSynopsis(): array
+ {
+ /** @var string[] $cleanedFunctions */
$cleanedFunctions = [];
- $file = file_get_contents($this->path);
+ $file = \file_get_contents($this->path);
if (!preg_match_all('/<\/?methodsynopsis[\s\S]*?>[\s\S]*?<\/methodsynopsis>/m', $file, $functions, PREG_SET_ORDER, 0)) {
return [];
}
$functions = $this->arrayFlatten($functions);
foreach ($functions as $function) {
- $cleaningFunction = preg_replace('/&(false);/m', 'FALSE', $function);
- $cleaningFunction = preg_replace('/&(true);/m', 'TRUE', $cleaningFunction);
+ $cleaningFunction = \str_replace(['&false;', '&true;', '&null;'], ['false', 'true', 'null'], $function);
$cleaningFunction = preg_replace('/&(.*);/m', '', $cleaningFunction);
+ if (!\is_string($cleaningFunction)) {
+ throw new \RuntimeException('Error occured in preg_replace');
+ }
$cleanedFunctions[] = $cleaningFunction;
}
$functionObjects = [];
foreach ($cleanedFunctions as $cleanedFunction) {
- $functionObjects[] = simplexml_load_string($cleanedFunction);
+ $functionObject = \simplexml_load_string($cleanedFunction);
+ if ($functionObject) {
+ $functionObjects[] = $functionObject;
+ }
}
return $functionObjects;
}
- /*
+ /**
+ * Loads the XML file, resolving all DTD declared entities.
+ *
+ * @return \SimpleXMLElement
+ */
+ public function loadAndResolveFile(): \SimpleXMLElement
+ {
+ $content = \file_get_contents($this->path);
+ $strpos = \strpos($content, '?>')+2;
+ if (!\file_exists(__DIR__.'/../doc/entities/generated.ent')) {
+ self::buildEntities();
+ }
+ $path = \realpath(__DIR__.'/../doc/entities/generated.ent');
+
+
+ $content = \substr($content, 0, $strpos)
+ .''
+ .\substr($content, $strpos+1);
+
+ echo 'Loading '.$this->path."\n";
+ $elem = \simplexml_load_string($content, \SimpleXMLElement::class, LIBXML_DTDLOAD | LIBXML_NOENT);
+ if ($elem === false) {
+ throw new \RuntimeException('Invalid XML file for '.$this->path);
+ }
+ $elem->registerXPathNamespace('docbook', 'http://docbook.org/ns/docbook');
+
+ return $elem;
+ }
+
+ /**
+ * Returns the module name in Camelcase.
+ *
+ * @return string
+ */
+ public function getModule(): string
+ {
+ return $this->toCamelCase(\basename(\dirname($this->path, 2)));
+ }
+
+ private function toCamelCase(string $str): string
+ {
+ $tokens = preg_split("/[_ ]+/", $str);
+ if ($tokens === false) {
+ throw new \RuntimeException('Unexpected preg_split error'); // @codeCoverageIgnore
+ }
+
+ $str = '';
+ foreach ($tokens as $token) {
+ $str .= ucfirst($token);
+ }
+
+ return $str;
+ }
+
+ /**
* @param mixed[] $array multidimensional string array
* @return string[]
*/
- private function arrayFlatten(array $array): array {
+ private function arrayFlatten(array $array): array
+ {
$result = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$result = array_merge($result, $this->arrayFlatten($value));
- }
- else {
+ } else {
$result[$key] = $value;
}
}
return $result;
}
-}
+ public static function buildEntities(): void
+ {
+ $file1 = \file_get_contents(__DIR__.'/../doc/doc-en/en/language-defs.ent');
+ $file2 = \file_get_contents(__DIR__.'/../doc/doc-en/en/language-snippets.ent');
+ $file3 = \file_get_contents(__DIR__.'/../doc/doc-en/en/extensions.ent');
+ $file4 = \file_get_contents(__DIR__.'/../doc/doc-en/doc-base/entities/global.ent');
+
+ $completeFile = $file1 . self::extractXmlHeader($file2) . self::extractXmlHeader($file3) . $file4;
+
+ \file_put_contents(__DIR__.'/../doc/entities/generated.ent', $completeFile);
+ }
+
+ private static function extractXmlHeader(string $content): string
+ {
+ $strpos = strpos($content, '?>')+2;
+ return substr($content, $strpos);
+ }
+}
diff --git a/src/FileCreator.php b/src/FileCreator.php
index c88f45a6..40a05f6c 100644
--- a/src/FileCreator.php
+++ b/src/FileCreator.php
@@ -8,15 +8,18 @@
class FileCreator
{
- public function __construct() {}
+ public function __construct()
+ {
+ }
- /*
+ /**
* This function generate an xls file
*
* @param string[] $protoFunctions
* @param string $path
*/
- public function generateXlsFile(array $protoFunctions, string $path): void {
+ public function generateXlsFile(array $protoFunctions, string $path): void
+ {
$spreadsheet = new Spreadsheet();
$numb = 1;
$status = '';
@@ -26,10 +29,10 @@ public function generateXlsFile(array $protoFunctions, string $path): void {
$sheet->setCellValue('B1', 'Status');
foreach ($protoFunctions as $protoFunction) {
- if ($protoFunction){
- if (strpos($protoFunction, '=') === FALSE && strpos($protoFunction, 'json') === FALSE) {
+ if ($protoFunction) {
+ if (strpos($protoFunction, '=') === false && strpos($protoFunction, 'json') === false) {
$status = 'classic';
- } else if (strpos($protoFunction, 'json')) {
+ } elseif (strpos($protoFunction, 'json')) {
$status = 'json';
} else {
$status = 'opt';
@@ -42,20 +45,67 @@ public function generateXlsFile(array $protoFunctions, string $path): void {
$writer->save($path);
}
- /*
+ /**
* This function generate an improved php lib function in a php file
*
- * @param string[]
- * @param string
+ * @param string[] $phpFunctions
+ * @param string $path
*/
- public function generatePhpFile(array $phpFunctions, string $path): void {
- $stream = fopen($path, 'w');
- fwrite($stream, "getFunctionName();
+ }, $functions);
+ $stream = fopen($path, 'w');
+ if ($stream === false) {
+ throw new \RuntimeException('Unable to write to '.$path);
}
+ fwrite($stream, "setName('generate')
+ ->setDescription('Generates the PHP file with all functions.')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+
+ $this->rmGenerated();
+ // Let's build the DTD necessary to load the XML files.
+ DocPage::buildEntities();
+ $excludedModules = [
+ 'snmp'
+ ];
+ $scanner = new Scanner(__DIR__ . '/../doc/doc-en/en/reference/*', $excludedModules);
+
+ [
+ 'functions' => $functions,
+ 'overloadedFunctions' => $overloadedFunctions
+ ] = $scanner->getMethods();
+
+ $output->writeln('These functions have been ignored and must be dealt with manually: '.\implode(', ', $overloadedFunctions));
+
+ $phpFunctions = [];
+ foreach ($functions as $function) {
+ $writePhpFunction = new WritePhpFunction($function);
+ $phpFunctions[] = $writePhpFunction->getPhpFunctionalFunction();
+ }
+
+ $fileCreator = new FileCreator();
+ //$fileCreator->generateXlsFile($protoFunctions, __DIR__ . '/../generated/lib.xls');
+ $fileCreator->generatePhpFile($phpFunctions, __DIR__ . '/../generated/lib.php');
+ $fileCreator->generateFunctionsList($functions, __DIR__ . '/../generated/functionsList.php');
+
+
+ $modules = [];
+ foreach ($functions as $function) {
+ $modules[$function->getModuleName()] = true;
+ }
+
+ foreach ($modules as $moduleName => $foo) {
+ $fileCreator->createExceptionFile($moduleName);
+ }
+
+ // Finally, let's require the generated file to check there is no error.
+ require __DIR__.'/../generated/lib.php';
+ }
+
+ private function rmGenerated(): void
+ {
+ $exceptions = \glob(__DIR__.'/../generated/Exceptions/*.php');
+
+ foreach ($exceptions as $exception) {
+ \unlink($exception);
+ }
+
+ if (\file_exists(__DIR__.'/../generated/lib.php')) {
+ \unlink(__DIR__.'/../generated/lib.php');
+ }
+ if (\file_exists(__DIR__.'/../doc/entities/generated.ent')) {
+ \unlink(__DIR__.'/../doc/entities/generated.ent');
+ }
+ }
+}
diff --git a/src/Method.php b/src/Method.php
index 578a7cc9..1b7bcc45 100644
--- a/src/Method.php
+++ b/src/Method.php
@@ -2,46 +2,213 @@
namespace Safe;
+use Safe\PhpStanFunctions\PhpStanFunction;
+use Safe\PhpStanFunctions\PhpStanFunctionMapReader;
+
class Method
{
/**
* @var \SimpleXMLElement
*/
private $functionObject;
-
- /*
- * @parameter \SimpleXMLElement $_functionObject
+ /**
+ * @var \SimpleXMLElement
+ */
+ private $rootEntity;
+ /**
+ * @var string
+ */
+ private $moduleName;
+ /**
+ * @var Parameter[]|null
*/
- public function __construct(\SimpleXMLElement $_functionObject) {
+ private $params = null;
+ /**
+ * @var PhpStanFunctionMapReader
+ */
+ private $phpStanFunctionMapReader;
+
+ public function __construct(\SimpleXMLElement $_functionObject, \SimpleXMLElement $rootEntity, string $moduleName, PhpStanFunctionMapReader $phpStanFunctionMapReader)
+ {
$this->functionObject = $_functionObject;
+ $this->rootEntity = $rootEntity;
+ $this->moduleName = $moduleName;
+ $this->phpStanFunctionMapReader = $phpStanFunctionMapReader;
}
- /*
- * @return string
- */
- public function getFunctionName(): string {
+ public function getFunctionName(): string
+ {
return $this->functionObject->methodname->__toString();
}
- /*
- * @return string
- */
- public function getFunctionType(): string {
- return $this->functionObject->type->__toString();
+ public function getFunctionType(): string
+ {
+ // If the function returns a boolean, since false is for error, true is for success.
+ // Let's replace this with a "void".
+ $type = $this->functionObject->type->__toString();
+ if ($type === 'bool') {
+ return 'void';
+ }
+ // Some types are completely weird. For instance, oci_new_collection returns a "OCI-Collection" (with a dash, yup)
+ if (\strpos($type, '-') !== false) {
+ return 'mixed';
+ }
+
+ return $type;
}
/**
* @return Parameter[]
*/
- public function getFunctionParam(): array {
- if (!isset($this->functionObject->methodparam)) {
- return [];
+ public function getFunctionParam(): array
+ {
+ if ($this->params === null) {
+ if (!isset($this->functionObject->methodparam)) {
+ return [];
+ }
+ $phpStanFunction = $this->getPhpStanData();
+ $params = [];
+ foreach ($this->functionObject->methodparam as $param) {
+ $params[] = new Parameter($param, $phpStanFunction);
+ }
+ $this->params = $params;
+ }
+ return $this->params;
+ }
+
+ public function getPhpDoc(): string
+ {
+ $str = "/**\n".
+ implode("\n", array_map(function (string $line) {
+ return ' * '.ltrim($line);
+ }, \explode("\n", \strip_tags($this->getDocBlock()))))
+ ."\n */\n";
+
+ return $str;
+ }
+
+ private function getDocBlock(): string
+ {
+ $str = $this->stripReturnFalseText($this->getStringForXPath("//docbook:refsect1[@role='description']/docbook:para"));
+ $str .= "\n\n";
+
+ $i=1;
+ foreach ($this->getFunctionParam() as $parameter) {
+ $str .= '@param '.$parameter->getBestType().' $'.$parameter->getParameter().' ';
+ $str .= $this->getStringForXPath("(//docbook:refsect1[@role='parameters']//docbook:varlistentry)[$i]//docbook:para")."\n";
+ $i++;
}
- $params = [];
- foreach ($this->functionObject->methodparam as $param) {
- $params[] = new Parameter($param);
+
+ $bestReturnType = $this->getBestReturnType();
+ if ($bestReturnType !== 'void') {
+ $str .= '@return '.$bestReturnType. ' ' .$this->getReturnDoc()."\n";
}
- return $params;
+
+ $str .= '@throws Exceptions\\'.$this->getModuleName(). "Exception\n";
+
+ return $str;
+ }
+
+ private function getReturnDoc(): string
+ {
+ $returnDoc = $this->getStringForXPath("//docbook:refsect1[@role='returnvalues']/docbook:para");
+ return $this->stripReturnFalseText($returnDoc);
}
-}
+ private function stripReturnFalseText(string $string): string
+ {
+ $string = \strip_tags($string);
+ $string = $this->removeString($string, 'or FALSE on failure');
+ $string = $this->removeString($string, 'on success, or FALSE otherwise');
+ $string = $this->removeString($string, 'or FALSE on error');
+ $string = $this->removeString($string, 'or FALSE if an error occurred');
+ $string = $this->removeString($string, 'the function will return TRUE, or FALSE otherwise');
+ return $string;
+ }
+
+ /**
+ * Removes a string, even if the string is split on multiple lines.
+ * @param string $string
+ * @param string $search
+ * @return string
+ */
+ private function removeString(string $string, string $search): string
+ {
+ $search = str_replace(' ', '\s+', $search);
+ return preg_replace('/'.$search.'/m', '', $string);
+ }
+
+ private function getStringForXPath(string $xpath): string
+ {
+ $paragraphs = $this->rootEntity->xpath($xpath);
+ if ($paragraphs === false) {
+ throw new \RuntimeException('Error while performing Xpath request.');
+ }
+ $str = '';
+ foreach ($paragraphs as $paragraph) {
+ $str .= $this->getInnerXml($paragraph)."\n\n";
+ }
+ return trim($str);
+ }
+
+ private function getBestReturnType(): ?string
+ {
+ $phpStanFunction = $this->getPhpStanData();
+ // Get the type from PhpStan database first, then from the php doc.
+ if ($phpStanFunction !== null) {
+ return $phpStanFunction->getReturnType();
+ } else {
+ return $this->getFunctionType();
+ }
+ }
+
+ private function getPhpStanData(): ?PhpStanFunction
+ {
+ $functionName = $this->getFunctionName();
+ if (!$this->phpStanFunctionMapReader->hasFunction($functionName)) {
+ return null;
+ }
+ return $this->phpStanFunctionMapReader->getFunction($functionName);
+ }
+
+ private function getInnerXml(\SimpleXMLElement $SimpleXMLElement): string
+ {
+ $element_name = $SimpleXMLElement->getName();
+ $inner_xml = $SimpleXMLElement->asXML();
+ if ($inner_xml === false) {
+ throw new \RuntimeException('Unable to serialize to XML');
+ }
+ $inner_xml = str_replace(['<'.$element_name.'>', ''.$element_name.'>'], '', $inner_xml);
+ $inner_xml = trim($inner_xml);
+ return $inner_xml;
+ }
+
+ public function getModuleName(): string
+ {
+ return $this->moduleName;
+ }
+
+ /**
+ * The function is overloaded if at least one parameter optional with no default value.
+ *
+ * @return bool
+ */
+ public function isOverloaded(): bool
+ {
+ foreach ($this->getFunctionParam() as $parameter) {
+ if ($parameter->isOptionalWithNoDefault()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public function cloneAndRemoveAParameter(): Method
+ {
+ $new = clone $this;
+ $params = $this->getFunctionParam();
+ \array_pop($params);
+ $new->params = $params;
+ return $new;
+ }
+}
diff --git a/src/Parameter.php b/src/Parameter.php
index 0ae1bf48..3eb8ab72 100644
--- a/src/Parameter.php
+++ b/src/Parameter.php
@@ -1,19 +1,28 @@
parameter = $parameter;
+ $this->phpStanFunction = $phpStanFunction;
}
- /*
+ /**
+ * Returns the type as declared in the doc.
* @return string
*/
public function getType(): string
@@ -21,17 +30,94 @@ public function getType(): string
return $this->parameter->type->__toString();
}
+ /**
+ * Returns the type as declared in the doc.
+ * @return string
+ */
+ public function getBestType(): string
+ {
+ // Get the type from PhpStan database first, then from the php doc.
+ if ($this->phpStanFunction !== null) {
+ $phpStanParameter = $this->phpStanFunction->getParameter($this->getParameter());
+ if ($phpStanParameter) {
+ return $phpStanParameter->getType();
+ }
+ }
+ return $this->getType();
+ }
+
/*
* @return string
*/
- public function getParameter(): string {
- return $this->parameter->parameter->__toString();
+ public function getParameter(): string
+ {
+ if ($this->isVariadic()) {
+ return 'params';
+ }
+ // The db2_bind_param method has parameters with a dash in it... yep... (patch submitted)
+ return \str_replace('-', '_', $this->parameter->parameter->__toString());
+ }
+
+ public function isByReference(): bool
+ {
+ return ((string)$this->parameter->parameter['role']) === 'reference';
}
+ /**
+ * Some parameters can be optional with no default value. In this case, the function is "overloaded" (which is not
+ * possible in user-land but possible in core...)
+ *
+ * @return bool
+ */
+ public function isOptionalWithNoDefault(): bool
+ {
+ return ((string)$this->parameter['choice']) === 'opt' && !$this->hasDefaultValue();
+ }
+
+ public function isVariadic(): bool
+ {
+ return $this->parameter->parameter->__toString() === '...';
+ }
+
+
/*
* @return string
*/
- public function getInitializer(): string {
- return $this->parameter->initializer->__toString();
+ public function getInitializer(): string
+ {
+ return \str_replace(['', ''], '', $this->getInnerXml($this->parameter->initializer));
+ }
+
+ public function hasDefaultValue(): bool
+ {
+ return isset($this->parameter->initializer);
+ }
+
+ public function getDefaultValue(): ?string
+ {
+ if (!$this->hasDefaultValue()) {
+ return null;
+ }
+
+ $initializer = $this->getInitializer();
+
+ // Some default value have weird values. For instance, first parameter of "mb_internal_encoding" has default value "mb_internal_encoding()"
+ if (strpos($initializer, '(') !== false) {
+ return null;
+ }
+
+ return $initializer;
+ }
+
+ private function getInnerXml(\SimpleXMLElement $SimpleXMLElement): string
+ {
+ $element_name = $SimpleXMLElement->getName();
+ $inner_xml = $SimpleXMLElement->asXML();
+ if ($inner_xml === false) {
+ throw new \RuntimeException('Unable to serialize to XML');
+ }
+ $inner_xml = str_replace(['<'.$element_name.'>', ''.$element_name.'>'], '', $inner_xml);
+ $inner_xml = trim($inner_xml);
+ return $inner_xml;
}
-}
\ No newline at end of file
+}
diff --git a/src/PathResearcher.php b/src/PathResearcher.php
deleted file mode 100644
index 64c3c824..00000000
--- a/src/PathResearcher.php
+++ /dev/null
@@ -1,52 +0,0 @@
-path = $_path;
- }
-
- /**
- * @return string[]
- */
- public function getPaths(): array
- {
- $incompletePaths = glob($this->path);
-
- $paths = [];
- foreach ($incompletePaths as $incompletePath) {
- $paths[] = glob($incompletePath.'/functions/*');
- }
- $paths = $this->arrayFlatten($paths);
- return ($paths);
- }
-
- /**
- * @param mixed[] $array
- * @return string[]
- */
- private function arrayFlatten(array $array): array {
- $result = array();
- foreach ($array as $key => $value) {
- if (is_array($value)) {
- $result = array_merge($result, $this->arrayFlatten($value));
- }
- else {
- $result[$key] = $value;
- }
- }
- return $result;
- }
-}
-
diff --git a/src/PhpStanFunctions/PhpStanFunction.php b/src/PhpStanFunctions/PhpStanFunction.php
new file mode 100644
index 00000000..7edd6ec6
--- /dev/null
+++ b/src/PhpStanFunctions/PhpStanFunction.php
@@ -0,0 +1,53 @@
+returnType = \array_shift($signature);
+ foreach ($signature as $name => $type) {
+ $param = new PhpStanParameter($name, $type);
+ $this->parameters[$param->getName()] = $param;
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getReturnType(): string
+ {
+ if ($this->returnType === 'bool') {
+ $this->returnType = 'void';
+ }
+ return \str_replace(['|bool', '|false'], '', $this->returnType);
+ }
+
+ /**
+ * @return array
+ */
+ public function getParameters(): array
+ {
+ return $this->parameters;
+ }
+
+ public function getParameter(string $name): ?PhpStanParameter
+ {
+ return $this->parameters[$name] ?? null;
+ }
+}
diff --git a/src/PhpStanFunctions/PhpStanFunctionMapReader.php b/src/PhpStanFunctions/PhpStanFunctionMapReader.php
new file mode 100644
index 00000000..7a4bd45c
--- /dev/null
+++ b/src/PhpStanFunctions/PhpStanFunctionMapReader.php
@@ -0,0 +1,29 @@
+
+ */
+ private $functionMap;
+
+ public function __construct()
+ {
+ $this->functionMap = require __DIR__.'/../../vendor/phpstan/phpstan/src/Reflection/SignatureMap/functionMap.php';
+ }
+
+ public function hasFunction(string $functionName): bool
+ {
+ return isset($this->functionMap[$functionName]);
+ }
+
+ public function getFunction(string $functionName): PhpStanFunction
+ {
+ return new PhpStanFunction($this->functionMap[$functionName]);
+ }
+}
diff --git a/src/PhpStanFunctions/PhpStanParameter.php b/src/PhpStanFunctions/PhpStanParameter.php
new file mode 100644
index 00000000..86d42aca
--- /dev/null
+++ b/src/PhpStanFunctions/PhpStanParameter.php
@@ -0,0 +1,92 @@
+optional = true;
+ }
+ if (\strpos($name, '...') !== false) {
+ $this->variadic = true;
+ }
+ if (\strpos($name, '&') !== false) {
+ $this->byReference = true;
+ }
+ $name = \str_replace(['&rw_', '&w_'], '', $name);
+ $name = trim($name, '=.&');
+
+ $this->name = $name;
+
+ if (\strpos($type, '?') !== false) {
+ $type = \str_replace('?', '', $type).'|null';
+ }
+
+ $this->type = $type;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ /**
+ * @return string
+ */
+ public function getType(): string
+ {
+ return $this->type;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isOptional(): bool
+ {
+ return $this->optional;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isVariadic(): bool
+ {
+ return $this->variadic;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isByReference(): bool
+ {
+ return $this->byReference;
+ }
+}
diff --git a/src/Scanner.php b/src/Scanner.php
new file mode 100644
index 00000000..273f945f
--- /dev/null
+++ b/src/Scanner.php
@@ -0,0 +1,79 @@
+path = $_path;
+ $this->excludedModules = $excludedModules;
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getPaths(): array
+ {
+ $incompletePaths = glob($this->path, GLOB_ONLYDIR);
+
+ $paths = [];
+ foreach ($incompletePaths as $incompletePath) {
+ $paths = array_merge($paths, glob($incompletePath.'/functions/*.xml'));
+ }
+ return $paths;
+ }
+
+ /**
+ * @return mixed[]
+ */
+ public function getMethods(): array
+ {
+ $functions = [];
+ $overloadedFunctions = [];
+ $paths = $this->getPaths();
+ $phpStanFunctionMapReader = new PhpStanFunctionMapReader();
+ foreach ($paths as $path) {
+ $module = \basename(\dirname($path, 2));
+ if (\in_array($module, $this->excludedModules)) {
+ continue;
+ }
+
+ $docPage = new DocPage($path);
+ if ($docPage->detectFalsyFunction()) {
+ $functionObjects = $docPage->getMethodSynopsis();
+ if (count($functionObjects) > 1) {
+ $overloadedFunctions = array_merge($overloadedFunctions, \array_map(function ($functionObject) {
+ return $functionObject->methodname->__toString();
+ }, $functionObjects));
+ continue;
+ }
+ $rootEntity = $docPage->loadAndResolveFile();
+ foreach ($functionObjects as $functionObject) {
+ $functions[] = new Method($functionObject, $rootEntity, $docPage->getModule(), $phpStanFunctionMapReader);
+ }
+ }
+ }
+
+ return [
+ 'functions' => $functions,
+ 'overloadedFunctions' => \array_unique($overloadedFunctions)
+ ];
+ }
+}
diff --git a/src/WritePhpFunction.php b/src/WritePhpFunction.php
index 30e81031..00911a13 100644
--- a/src/WritePhpFunction.php
+++ b/src/WritePhpFunction.php
@@ -17,11 +17,13 @@ public function __construct(Method $method)
/*
* @return string
*/
- public function getPhpPrototypeFunction(): string {
- if ($this->method->getFunctionName() && strpos($this->method->getFunctionType(), 'void') === FALSE)
- return 'function '.$this->method->getFunctionName().'('.$this->displayParamsWithType().')'.': '.$this->method->getFunctionType().'{}';
- else
+ public function getPhpPrototypeFunction(): string
+ {
+ if ($this->method->getFunctionName()) {
+ return 'function '.$this->method->getFunctionName().'('.$this->displayParamsWithType($this->method->getFunctionParam()).')'.': '.$this->method->getFunctionType().'{}';
+ } else {
return '';
+ }
}
/*
@@ -30,50 +32,122 @@ public function getPhpPrototypeFunction(): string {
public function getPhpFunctionalFunction(): string
{
if ($this->getPhpPrototypeFunction()) {
- return $phpFunction = $this->writePhpFunction();
+ return $this->writePhpFunction();
}
- return $phpFunction = '';
+ return '';
}
/*
* return string
*/
- private function writePhpFunction(): string {
- if (strpos($this->method->getFunctionType(), 'void') !== FALSE) {
- return '';
+ private function writePhpFunction(): string
+ {
+ $phpFunction = $this->method->getPhpDoc();
+ if ($this->method->getFunctionType() !== 'mixed' && $this->method->getFunctionType() !== 'resource') {
+ $returnType = ': ' . $this->method->getFunctionType();
+ } else {
+ $returnType = '';
}
- $phpFunction = "function {$this->method->getFunctionName()}({$this->displayParamsWithType()}): {$this->method->getFunctionType()} {
- \$params = func_get_args();
- if ((\${$this->method->getFunctionType()} = \\{$this->method->getFunctionName()}(...\$params)) === FALSE) {
- \$error = error_get_last();
- throw new FileWritingException(\$error['message']);
+ $returnStatement = '';
+ if ($this->method->getFunctionType() !== 'void') {
+ $returnStatement = " return \$result;\n";
+ }
+ $moduleName = $this->method->getModuleName();
+
+ $phpFunction .= "function {$this->method->getFunctionName()}({$this->displayParamsWithType($this->method->getFunctionParam())}){$returnType}
+{
+ error_clear_last();
+";
+
+ if (!$this->method->isOverloaded()) {
+ $phpFunction .= ' $result = '.$this->printFunctionCall($this->method);
+ } else {
+ $method = $this->method;
+ $inElse = false;
+ do {
+ $lastParameter = $method->getFunctionParam()[count($method->getFunctionParam())-1];
+ if ($inElse) {
+ $phpFunction .= ' else';
+ } else {
+ $phpFunction .= ' ';
+ }
+ $defaultValue = $lastParameter->getDefaultValue();
+ $defaultValueToString = ($defaultValue === null) ? 'null' : $defaultValue;
+ $phpFunction .= 'if ($'.$lastParameter->getParameter().' !== '.$defaultValueToString.') {'."\n";
+ $phpFunction .= ' $result = '.$this->printFunctionCall($method)."\n";
+ $phpFunction .= ' }';
+ $inElse = true;
+ $method = $method->cloneAndRemoveAParameter();
+ if (!$method->isOverloaded()) {
+ break;
+ }
+ } while (true);
+ $phpFunction .= 'else {'."\n";
+ $phpFunction .= ' $result = '.$this->printFunctionCall($method)."\n";
+ $phpFunction .= ' }';
}
- return \${$this->method->getFunctionType()};
- }\n\n
- ";
+
+ $phpFunction .= $this->generateExceptionCode($moduleName, $this->method).$returnStatement. '}
+
+';
+
return $phpFunction;
}
- /*
+ private function generateExceptionCode(string $moduleName, Method $method) : string
+ {
+ // Special case for CURL: we need the first argument of the method if this is a resource.
+ if ($moduleName === 'Curl') {
+ $params = $method->getFunctionParam();
+ if (\count($params) > 0 && $params[0]->getParameter() === 'ch') {
+ return "
+ if (\$result === FALSE) {
+ throw Exceptions\\CurlException::createFromCurlResource(\$ch);
+ }
+";
+ }
+ }
+
+ return "
+ if (\$result === FALSE) {
+ throw Exceptions\\{$moduleName}Exception::createFromPhpError();
+ }
+";
+ }
+
+ /**
+ * @param Parameter[] $params
* @return string
*/
- private function displayParamsWithType(): string {
- $params = $this->method->getFunctionParam();
+ private function displayParamsWithType(array $params): string
+ {
$paramsAsString = [];
- $optDectected = FALSE;
+ $optDetected = false;
+
+ foreach ($params as $param) {
+ $paramAsString = '';
+ if ($param->getType() !== 'mixed' && $param->getType() !== 'resource') {
+ $paramAsString = $param->getType().' ';
+ }
- foreach($params as $param) {
- if ($param->getType() == "mixed" || $param->getType() == "resource") {
- $paramAsString = '$'.$param->getParameter();
+ $paramName = $param->getParameter();
+ if ($param->isVariadic()) {
+ $paramAsString .= ' ...$'.$paramName;
} else {
- $paramAsString = $param->getType().' $'.$param->getParameter();
+ if ($param->isByReference()) {
+ $paramAsString .= '&';
+ }
+ $paramAsString .= '$'.$paramName;
}
- if ($param->getInitializer() != null) {
- $paramAsString .= ' = '.$param->getInitializer();
- $optDectected = TRUE;
- } else if ($optDectected) {
+ if ($param->hasDefaultValue()) {
+ $optDetected = true;
+ }
+ $defaultValue = $param->getDefaultValue();
+ if ($defaultValue !== null) {
+ $paramAsString .= ' = '.$defaultValue;
+ } elseif ($optDetected && !$param->isVariadic()) {
$paramAsString .= ' = null';
}
$paramsAsString[] = $paramAsString;
@@ -81,4 +155,14 @@ private function displayParamsWithType(): string {
return implode(', ', $paramsAsString);
}
+
+ private function printFunctionCall(Method $function): string
+ {
+ $functionCall = '\\'.$function->getFunctionName().'(';
+ $functionCall .= implode(', ', \array_map(function (Parameter $parameter) {
+ return '$'.$parameter->getParameter();
+ }, $function->getFunctionParam()));
+ $functionCall .= ');';
+ return $functionCall;
+ }
}
diff --git a/tests/MethodTest.php b/tests/MethodTest.php
index ef8ada26..7885b7ac 100644
--- a/tests/MethodTest.php
+++ b/tests/MethodTest.php
@@ -3,31 +3,32 @@
namespace Safe;
use PHPUnit\Framework\TestCase;
+use Safe\PhpStanFunctions\PhpStanFunctionMapReader;
class MethodTest extends TestCase
{
public function testGetFunctionName() {
$docPage = new DocPage(__DIR__ . '/../doc/doc-en/en/reference/pcre/functions/preg-match.xml');
$xmlObject = $docPage->getMethodSynopsis();
- $method = new Method($xmlObject);
+ $method = new Method($xmlObject[0], $docPage->loadAndResolveFile(), $docPage->getModule(), new PhpStanFunctionMapReader());
$name = $method->getFunctionName();
- $this->assertEquals(0, strcmp('preg_match', $name[0]));
+ $this->assertEquals('preg_match', $name);
}
public function testGetFunctionType() {
$docPage = new DocPage(__DIR__ . '/../doc/doc-en/en/reference/pcre/functions/preg-match.xml');
$xmlObject = $docPage->getMethodSynopsis();
- $method = new Method($xmlObject);
+ $method = new Method($xmlObject[0], $docPage->loadAndResolveFile(), $docPage->getModule(), new PhpStanFunctionMapReader());
$type = $method->getFunctionType();
- $this->assertEquals(0, strcmp('int', $type[0]));
+ $this->assertEquals('int', $type);
}
public function testGetFunctionParam() {
$docPage = new DocPage(__DIR__ . '/../doc/doc-en/en/reference/pcre/functions/preg-match.xml');
$xmlObject = $docPage->getMethodSynopsis();
- $method = new Method($xmlObject);
+ $method = new Method($xmlObject[0], $docPage->loadAndResolveFile(), $docPage->getModule(), new PhpStanFunctionMapReader());
$params = $method->getFunctionParam();
- $this->assertEquals(0, strcmp('string', $params[0]['type']));
- $this->assertEquals(0, strcmp('pattern', $params[0]['parameter']));
+ $this->assertEquals('string', $params[0]->getType());
+ $this->assertEquals('pattern', $params[0]->getParameter());
}
}
diff --git a/tests/PhpStanFunctions/PhpStanFunctionMapReaderTest.php b/tests/PhpStanFunctions/PhpStanFunctionMapReaderTest.php
new file mode 100644
index 00000000..713da061
--- /dev/null
+++ b/tests/PhpStanFunctions/PhpStanFunctionMapReaderTest.php
@@ -0,0 +1,32 @@
+assertTrue($mapReader->hasFunction('strpos'));
+ $this->assertFalse($mapReader->hasFunction('foobar'));
+ }
+
+ public function testGet(): void
+ {
+ $mapReader = new PhpStanFunctionMapReader();
+ $function = $mapReader->getFunction('apcu_fetch');
+
+
+ // 'apcu_fetch' => ['mixed', 'key'=>'string|string[]', '&w_success='=>'bool'],
+ $this->assertSame('mixed', $function->getReturnType());
+ $parameters = $function->getParameters();
+ $this->assertCount(2, $parameters);
+ $this->assertSame('success', $parameters['success']->getName());
+ $this->assertSame('bool', $parameters['success']->getType());
+ $this->assertFalse($parameters['success']->isVariadic());
+ $this->assertTrue($parameters['success']->isByReference());
+ $this->assertTrue($parameters['success']->isOptional());
+ }
+}