├── .gitattributes ├── .gitignore ├── .php_cs ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── phpunit.xml ├── src ├── Checks │ ├── AllInOneCheck.php │ ├── CheckInterface.php │ ├── HttpCheck.php │ ├── PDOCheck.php │ ├── PredisCheck.php │ ├── RedisCheck.php │ ├── SocketCheck.php │ └── SocketConnectionCheck.php ├── SocketClient.php └── Status.php └── tests ├── Checks ├── AllInOneCheckTest.php ├── HttpCheckTest.php ├── PDOCheckTest.php ├── PredisCheckTest.php ├── RedisCheckTest.php ├── SocketCheckTest.php └── SocketConnectionCheckTest.php ├── Resource └── jmock │ └── one.json ├── docker-compose.yml └── realtime_test.php /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | composer.phar 2 | /vendor/ 3 | 4 | # Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control 5 | # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file 6 | # composer.lock 7 | .phpunit.result.cache 8 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | in([__DIR__ . '/src']); 4 | 5 | return PhpCsFixer\Config::create() 6 | ->setRules([ 7 | '@PSR1' => true, 8 | '@PSR2' => true, 9 | '@Symfony' => true, 10 | '@DoctrineAnnotation' => true, 11 | 'psr4' => true, 12 | 'array_syntax' => ['syntax' => 'short'], 13 | 'mb_str_functions' => true, 14 | 'no_null_property_initialization' => true, 15 | 'no_php4_constructor' => true, 16 | 'no_short_echo_tag' => true, 17 | 'no_useless_else' => true, 18 | 'no_useless_return' => true, 19 | 'ordered_imports' => true, 20 | 'strict_comparison' => false, 21 | 'strict_param' => false, 22 | 'native_function_invocation' => true, 23 | 'phpdoc_add_missing_param_annotation' => true, 24 | 'phpdoc_types_order' => true, 25 | 'phpdoc_order' => true, 26 | 'no_superfluous_phpdoc_tags' => [ 27 | 'allow_mixed' => true, 28 | ], 29 | 'method_argument_space' => [ 30 | 'on_multiline' => 'ensure_fully_multiline', 31 | ], 32 | 'explicit_string_variable' => true, 33 | 'simple_to_complex_string_variable' => true, 34 | // extra 35 | 'modernize_types_casting' => true, 36 | 'method_chaining_indentation' => true, 37 | 'linebreak_after_opening_tag' => true, 38 | ]) 39 | ->setRiskyAllowed(true) 40 | ->setFinder($finder) 41 | ->setUsingCache(false) 42 | ; 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Eugene Bravov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Health checks for external services 2 | 3 | ## Install 4 | 5 | ```bash 6 | composer require fullpipe/check-them 7 | ``` 8 | 9 | ## Usage 10 | 11 | ```php 12 | use Fullpipe\CheckThem\Checks\PDOCheck; 13 | 14 | $mysqlCheck = new PDOCheck('mysql:dbname=test_db;host=127.0.0.1:3306', 'username', 'password'); 15 | $status = $mysqlCheck->getStatus(); 16 | 17 | if(!$status->isUp()) { 18 | $this->logger->warn('Mysql server is down', $status->getError()); 19 | exit; 20 | } 21 | ``` 22 | 23 | or use AllInOneCheck 24 | 25 | ```php 26 | 27 | use Fullpipe\CheckThem\Checks\AllInOneCheck; 28 | use Fullpipe\CheckThem\Checks\PDOCheck; 29 | use Fullpipe\CheckThem\Checks\HttpCheck; 30 | use Fullpipe\CheckThem\Checks\RedisChecker; 31 | 32 | ... 33 | 34 | $allInOne = new AllInOneCheck(); 35 | 36 | $allInOne->add(new PDOCheck('mysql:dbname=test_db;host=127.0.0.1:3306', 'username', 'password')); 37 | $allInOne->add(new HttpCheck('user_service:8080')); 38 | $allInOne->add(new RedisChecker('redis:6379')); 39 | 40 | $status = $allInOne->getStatus(); 41 | 42 | if(!$status->isUp()) { 43 | $this->logger->warn('Something is down', $status->getError()); 44 | exit; 45 | } 46 | 47 | // everything is fine 48 | ``` 49 | 50 | ## Available checks 51 | 52 | ### PDOCheck 53 | 54 | It is just a simple wrapper over [php.PDO](https://www.php.net/manual/en/book.pdo.php). 55 | It has the same constructor signature as the `PDO` class. In theory, it works with all 56 | [PDO drivers](https://www.php.net/manual/en/pdo.drivers.php), but was tested 57 | only against MySQL and Postgres. 58 | 59 | 60 | #### Examples 61 | 62 | ```php 63 | use Fullpipe\CheckThem\Checks\PDOCheck; 64 | 65 | ... 66 | 67 | $mysqlCheck = new PDOCheck('mysql:dbname=test_db;host=127.0.0.1:3306', 'username', 'password'); 68 | $pgCheck = new PDOCheck('pgsql:host=localhost;port=8002;dbname=test_db', 'username', 'password'); 69 | ``` 70 | 71 | ### HttpCheck 72 | 73 | Check external service by http request. To be `up` service should respond with 74 | `200` http code. 75 | 76 | #### Examples 77 | 78 | ```php 79 | use Fullpipe\CheckThem\Checks\HttpCheck; 80 | 81 | ... 82 | 83 | $userCheck = new HttpCheck('http://user_service:8080/healthz'); 84 | $webCheck = new HttpCheck('https://google.com/'); 85 | ``` 86 | 87 | #### Config 88 | 89 | ```php 90 | $check = (new HttpCheck('http://user_service:8080/healthz')) 91 | ->setConnectionTimeout(3) // change connection timeout, default 1 second 92 | ; 93 | ``` 94 | 95 | ### RedisCheck 96 | 97 | Checks redis server with `PING` -> `PONG` request. 98 | 99 | #### Examples 100 | 101 | ```php 102 | use Fullpipe\CheckThem\Checks\RedisCheck; 103 | 104 | ... 105 | 106 | $check = new RedisCheck('tcp://10.0.0.1:6379'); 107 | $check = new RedisCheck('unix:/path/to/redis.sock'); 108 | ``` 109 | 110 | #### Config 111 | 112 | ```php 113 | $check = (new RedisCheck('redis:6379')) 114 | ->setAuth('test_pass') // use password if required 115 | ->setConnectionTimeout(4) // timeout for server connection, default 1 second 116 | ->setStreamTimeout(3) // timeout for socket read/write operations, default 1 second 117 | ; 118 | ``` 119 | 120 | ### PredisCheck 121 | 122 | If you already work with redis using [predis](https://github.com/predis/predis). 123 | You could use predis client for `PING` check. 124 | 125 | #### Examples 126 | 127 | ```php 128 | use Fullpipe\CheckThem\Checks\PredisCheck; 129 | 130 | ... 131 | 132 | $client = new Predis\Client([ 133 | 'scheme' => 'tcp', 134 | 'host' => '10.0.0.1', 135 | 'port' => 6379, 136 | ]); 137 | $check = new PredisCheck($client); 138 | ``` 139 | 140 | ### SocketCheck 141 | 142 | Connects to service and waits for single char from service over a socket connection. 143 | 144 | #### Examples 145 | 146 | ```php 147 | use Fullpipe\CheckThem\Checks\SocketCheck; 148 | 149 | ... 150 | 151 | // you could use this check for mysql, 152 | // it work fine and you don't need a password 153 | $check = new SocketCheck('mysql:3306'); 154 | ``` 155 | 156 | #### Config 157 | 158 | ```php 159 | $check = (new SocketCheck('mysql:3306')) 160 | ->setConnectionTimeout(4) // timeout for server connection, default 1 second 161 | ->setStreamTimeout(3) // timeout for socket read/write operations, default 1 second 162 | ; 163 | ``` 164 | 165 | ### SocketConnectionCheck 166 | 167 | Checks only that socket connection is working. It is not the check that you 168 | could rely on. 169 | 170 | #### Examples 171 | 172 | ```php 173 | use Fullpipe\CheckThem\Checks\SocketConnectionCheck; 174 | 175 | ... 176 | 177 | $check = new SocketConnectionCheck('rabbitmq:5672'); 178 | ``` 179 | 180 | #### Config 181 | 182 | ```php 183 | $check = (new SocketConnectionCheck('mysql:3306')) 184 | ->setConnectionTimeout(4) // timeout for server connection, default 1 second 185 | ; 186 | ``` 187 | 188 | ### AllInOneCheck 189 | 190 | Checks all children to be available. 191 | 192 | #### Examples 193 | 194 | ```php 195 | use Fullpipe\CheckThem\Checks\AllInOneCheck; 196 | use Fullpipe\CheckThem\Checks\SocketCheck; 197 | use Fullpipe\CheckThem\Checks\RedisCheck; 198 | 199 | ... 200 | 201 | $check = (new AllInOneCheck()) 202 | ->add(new SocketCheck('mysql:3306')) 203 | ->add((new RedisCheck('tcp://10.0.0.1:6379'))->setAuth('redisPass')) 204 | ; 205 | ``` 206 | 207 | ## Test 208 | 209 | ```bash 210 | composer install 211 | docker-compose -f tests/docker-compose.yml up -d 212 | ./vendor/bin/phpunit 213 | ``` 214 | 215 | or if you want to play with service availability 216 | 217 | ```bash 218 | docker-compose -f tests/docker-compose.yml up -d 219 | php ./tests/realtime_test.php 220 | docker-compose -f tests/docker-compose.yml restart mysql57 221 | ``` 222 | 223 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fullpipe/check-them", 3 | "description": "Health checks for external services", 4 | "keywords": ["healthz", "health check", "k8s"], 5 | "type": "library", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Eugene Bravov", 10 | "email": "eugene.bravov@gmail.com" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=7.2.0" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Fullpipe\\CheckThem\\": "src/" 19 | } 20 | }, 21 | "require-dev": { 22 | "phpunit/phpunit": "^9.4", 23 | "friendsofphp/php-cs-fixer": "^2.16", 24 | "predis/predis": "^1.1", 25 | "symfony/console": "^5.1" 26 | }, 27 | "autoload-dev": { 28 | "psr-4": { 29 | "tests\\": "tests/" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "1c02de7d2b0efad23bff855e14484237", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "composer/semver", 12 | "version": "3.2.2", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/composer/semver.git", 16 | "reference": "4089fddb67bcf6bf860d91b979e95be303835002" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/composer/semver/zipball/4089fddb67bcf6bf860d91b979e95be303835002", 21 | "reference": "4089fddb67bcf6bf860d91b979e95be303835002", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": "^5.3.2 || ^7.0 || ^8.0" 26 | }, 27 | "require-dev": { 28 | "phpstan/phpstan": "^0.12.19", 29 | "symfony/phpunit-bridge": "^4.2 || ^5" 30 | }, 31 | "type": "library", 32 | "extra": { 33 | "branch-alias": { 34 | "dev-main": "3.x-dev" 35 | } 36 | }, 37 | "autoload": { 38 | "psr-4": { 39 | "Composer\\Semver\\": "src" 40 | } 41 | }, 42 | "notification-url": "https://packagist.org/downloads/", 43 | "license": [ 44 | "MIT" 45 | ], 46 | "authors": [ 47 | { 48 | "name": "Nils Adermann", 49 | "email": "naderman@naderman.de", 50 | "homepage": "http://www.naderman.de" 51 | }, 52 | { 53 | "name": "Jordi Boggiano", 54 | "email": "j.boggiano@seld.be", 55 | "homepage": "http://seld.be" 56 | }, 57 | { 58 | "name": "Rob Bast", 59 | "email": "rob.bast@gmail.com", 60 | "homepage": "http://robbast.nl" 61 | } 62 | ], 63 | "description": "Semver library that offers utilities, version constraint parsing and validation.", 64 | "keywords": [ 65 | "semantic", 66 | "semver", 67 | "validation", 68 | "versioning" 69 | ], 70 | "support": { 71 | "irc": "irc://irc.freenode.org/composer", 72 | "issues": "https://github.com/composer/semver/issues", 73 | "source": "https://github.com/composer/semver/tree/3.2.2" 74 | }, 75 | "funding": [ 76 | { 77 | "url": "https://packagist.com", 78 | "type": "custom" 79 | }, 80 | { 81 | "url": "https://github.com/composer", 82 | "type": "github" 83 | }, 84 | { 85 | "url": "https://tidelift.com/funding/github/packagist/composer/composer", 86 | "type": "tidelift" 87 | } 88 | ], 89 | "time": "2020-10-14T08:51:15+00:00" 90 | }, 91 | { 92 | "name": "composer/xdebug-handler", 93 | "version": "1.4.4", 94 | "source": { 95 | "type": "git", 96 | "url": "https://github.com/composer/xdebug-handler.git", 97 | "reference": "6e076a124f7ee146f2487554a94b6a19a74887ba" 98 | }, 99 | "dist": { 100 | "type": "zip", 101 | "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6e076a124f7ee146f2487554a94b6a19a74887ba", 102 | "reference": "6e076a124f7ee146f2487554a94b6a19a74887ba", 103 | "shasum": "" 104 | }, 105 | "require": { 106 | "php": "^5.3.2 || ^7.0 || ^8.0", 107 | "psr/log": "^1.0" 108 | }, 109 | "require-dev": { 110 | "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" 111 | }, 112 | "type": "library", 113 | "autoload": { 114 | "psr-4": { 115 | "Composer\\XdebugHandler\\": "src" 116 | } 117 | }, 118 | "notification-url": "https://packagist.org/downloads/", 119 | "license": [ 120 | "MIT" 121 | ], 122 | "authors": [ 123 | { 124 | "name": "John Stevenson", 125 | "email": "john-stevenson@blueyonder.co.uk" 126 | } 127 | ], 128 | "description": "Restarts a process without Xdebug.", 129 | "keywords": [ 130 | "Xdebug", 131 | "performance" 132 | ], 133 | "support": { 134 | "irc": "irc://irc.freenode.org/composer", 135 | "issues": "https://github.com/composer/xdebug-handler/issues", 136 | "source": "https://github.com/composer/xdebug-handler/tree/1.4.4" 137 | }, 138 | "funding": [ 139 | { 140 | "url": "https://packagist.com", 141 | "type": "custom" 142 | }, 143 | { 144 | "url": "https://github.com/composer", 145 | "type": "github" 146 | }, 147 | { 148 | "url": "https://tidelift.com/funding/github/packagist/composer/composer", 149 | "type": "tidelift" 150 | } 151 | ], 152 | "time": "2020-10-24T12:39:10+00:00" 153 | }, 154 | { 155 | "name": "doctrine/annotations", 156 | "version": "1.11.1", 157 | "source": { 158 | "type": "git", 159 | "url": "https://github.com/doctrine/annotations.git", 160 | "reference": "ce77a7ba1770462cd705a91a151b6c3746f9c6ad" 161 | }, 162 | "dist": { 163 | "type": "zip", 164 | "url": "https://api.github.com/repos/doctrine/annotations/zipball/ce77a7ba1770462cd705a91a151b6c3746f9c6ad", 165 | "reference": "ce77a7ba1770462cd705a91a151b6c3746f9c6ad", 166 | "shasum": "" 167 | }, 168 | "require": { 169 | "doctrine/lexer": "1.*", 170 | "ext-tokenizer": "*", 171 | "php": "^7.1 || ^8.0" 172 | }, 173 | "require-dev": { 174 | "doctrine/cache": "1.*", 175 | "doctrine/coding-standard": "^6.0 || ^8.1", 176 | "phpstan/phpstan": "^0.12.20", 177 | "phpunit/phpunit": "^7.5 || ^9.1.5" 178 | }, 179 | "type": "library", 180 | "extra": { 181 | "branch-alias": { 182 | "dev-master": "1.11.x-dev" 183 | } 184 | }, 185 | "autoload": { 186 | "psr-4": { 187 | "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" 188 | } 189 | }, 190 | "notification-url": "https://packagist.org/downloads/", 191 | "license": [ 192 | "MIT" 193 | ], 194 | "authors": [ 195 | { 196 | "name": "Guilherme Blanco", 197 | "email": "guilhermeblanco@gmail.com" 198 | }, 199 | { 200 | "name": "Roman Borschel", 201 | "email": "roman@code-factory.org" 202 | }, 203 | { 204 | "name": "Benjamin Eberlei", 205 | "email": "kontakt@beberlei.de" 206 | }, 207 | { 208 | "name": "Jonathan Wage", 209 | "email": "jonwage@gmail.com" 210 | }, 211 | { 212 | "name": "Johannes Schmitt", 213 | "email": "schmittjoh@gmail.com" 214 | } 215 | ], 216 | "description": "Docblock Annotations Parser", 217 | "homepage": "https://www.doctrine-project.org/projects/annotations.html", 218 | "keywords": [ 219 | "annotations", 220 | "docblock", 221 | "parser" 222 | ], 223 | "support": { 224 | "issues": "https://github.com/doctrine/annotations/issues", 225 | "source": "https://github.com/doctrine/annotations/tree/1.11.1" 226 | }, 227 | "time": "2020-10-26T10:28:16+00:00" 228 | }, 229 | { 230 | "name": "doctrine/instantiator", 231 | "version": "1.3.1", 232 | "source": { 233 | "type": "git", 234 | "url": "https://github.com/doctrine/instantiator.git", 235 | "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" 236 | }, 237 | "dist": { 238 | "type": "zip", 239 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", 240 | "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", 241 | "shasum": "" 242 | }, 243 | "require": { 244 | "php": "^7.1 || ^8.0" 245 | }, 246 | "require-dev": { 247 | "doctrine/coding-standard": "^6.0", 248 | "ext-pdo": "*", 249 | "ext-phar": "*", 250 | "phpbench/phpbench": "^0.13", 251 | "phpstan/phpstan-phpunit": "^0.11", 252 | "phpstan/phpstan-shim": "^0.11", 253 | "phpunit/phpunit": "^7.0" 254 | }, 255 | "type": "library", 256 | "extra": { 257 | "branch-alias": { 258 | "dev-master": "1.2.x-dev" 259 | } 260 | }, 261 | "autoload": { 262 | "psr-4": { 263 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 264 | } 265 | }, 266 | "notification-url": "https://packagist.org/downloads/", 267 | "license": [ 268 | "MIT" 269 | ], 270 | "authors": [ 271 | { 272 | "name": "Marco Pivetta", 273 | "email": "ocramius@gmail.com", 274 | "homepage": "http://ocramius.github.com/" 275 | } 276 | ], 277 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 278 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html", 279 | "keywords": [ 280 | "constructor", 281 | "instantiate" 282 | ], 283 | "support": { 284 | "issues": "https://github.com/doctrine/instantiator/issues", 285 | "source": "https://github.com/doctrine/instantiator/tree/1.3.x" 286 | }, 287 | "funding": [ 288 | { 289 | "url": "https://www.doctrine-project.org/sponsorship.html", 290 | "type": "custom" 291 | }, 292 | { 293 | "url": "https://www.patreon.com/phpdoctrine", 294 | "type": "patreon" 295 | }, 296 | { 297 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", 298 | "type": "tidelift" 299 | } 300 | ], 301 | "time": "2020-05-29T17:27:14+00:00" 302 | }, 303 | { 304 | "name": "doctrine/lexer", 305 | "version": "1.2.1", 306 | "source": { 307 | "type": "git", 308 | "url": "https://github.com/doctrine/lexer.git", 309 | "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" 310 | }, 311 | "dist": { 312 | "type": "zip", 313 | "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", 314 | "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", 315 | "shasum": "" 316 | }, 317 | "require": { 318 | "php": "^7.2 || ^8.0" 319 | }, 320 | "require-dev": { 321 | "doctrine/coding-standard": "^6.0", 322 | "phpstan/phpstan": "^0.11.8", 323 | "phpunit/phpunit": "^8.2" 324 | }, 325 | "type": "library", 326 | "extra": { 327 | "branch-alias": { 328 | "dev-master": "1.2.x-dev" 329 | } 330 | }, 331 | "autoload": { 332 | "psr-4": { 333 | "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" 334 | } 335 | }, 336 | "notification-url": "https://packagist.org/downloads/", 337 | "license": [ 338 | "MIT" 339 | ], 340 | "authors": [ 341 | { 342 | "name": "Guilherme Blanco", 343 | "email": "guilhermeblanco@gmail.com" 344 | }, 345 | { 346 | "name": "Roman Borschel", 347 | "email": "roman@code-factory.org" 348 | }, 349 | { 350 | "name": "Johannes Schmitt", 351 | "email": "schmittjoh@gmail.com" 352 | } 353 | ], 354 | "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", 355 | "homepage": "https://www.doctrine-project.org/projects/lexer.html", 356 | "keywords": [ 357 | "annotations", 358 | "docblock", 359 | "lexer", 360 | "parser", 361 | "php" 362 | ], 363 | "support": { 364 | "issues": "https://github.com/doctrine/lexer/issues", 365 | "source": "https://github.com/doctrine/lexer/tree/1.2.1" 366 | }, 367 | "funding": [ 368 | { 369 | "url": "https://www.doctrine-project.org/sponsorship.html", 370 | "type": "custom" 371 | }, 372 | { 373 | "url": "https://www.patreon.com/phpdoctrine", 374 | "type": "patreon" 375 | }, 376 | { 377 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", 378 | "type": "tidelift" 379 | } 380 | ], 381 | "time": "2020-05-25T17:44:05+00:00" 382 | }, 383 | { 384 | "name": "friendsofphp/php-cs-fixer", 385 | "version": "v2.16.7", 386 | "source": { 387 | "type": "git", 388 | "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", 389 | "reference": "4e35806a6d7d8510d6842ae932e8832363d22c87" 390 | }, 391 | "dist": { 392 | "type": "zip", 393 | "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/4e35806a6d7d8510d6842ae932e8832363d22c87", 394 | "reference": "4e35806a6d7d8510d6842ae932e8832363d22c87", 395 | "shasum": "" 396 | }, 397 | "require": { 398 | "composer/semver": "^1.4 || ^2.0 || ^3.0", 399 | "composer/xdebug-handler": "^1.2", 400 | "doctrine/annotations": "^1.2", 401 | "ext-json": "*", 402 | "ext-tokenizer": "*", 403 | "php": "^7.1", 404 | "php-cs-fixer/diff": "^1.3", 405 | "symfony/console": "^3.4.43 || ^4.1.6 || ^5.0", 406 | "symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0", 407 | "symfony/filesystem": "^3.0 || ^4.0 || ^5.0", 408 | "symfony/finder": "^3.0 || ^4.0 || ^5.0", 409 | "symfony/options-resolver": "^3.0 || ^4.0 || ^5.0", 410 | "symfony/polyfill-php70": "^1.0", 411 | "symfony/polyfill-php72": "^1.4", 412 | "symfony/process": "^3.0 || ^4.0 || ^5.0", 413 | "symfony/stopwatch": "^3.0 || ^4.0 || ^5.0" 414 | }, 415 | "require-dev": { 416 | "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", 417 | "justinrainbow/json-schema": "^5.0", 418 | "keradus/cli-executor": "^1.4", 419 | "mikey179/vfsstream": "^1.6", 420 | "php-coveralls/php-coveralls": "^2.4.1", 421 | "php-cs-fixer/accessible-object": "^1.0", 422 | "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", 423 | "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", 424 | "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.1", 425 | "phpunitgoodpractices/traits": "^1.9.1", 426 | "symfony/phpunit-bridge": "^5.1", 427 | "symfony/yaml": "^3.0 || ^4.0 || ^5.0" 428 | }, 429 | "suggest": { 430 | "ext-dom": "For handling output formats in XML", 431 | "ext-mbstring": "For handling non-UTF8 characters.", 432 | "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", 433 | "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", 434 | "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." 435 | }, 436 | "bin": [ 437 | "php-cs-fixer" 438 | ], 439 | "type": "application", 440 | "autoload": { 441 | "psr-4": { 442 | "PhpCsFixer\\": "src/" 443 | }, 444 | "classmap": [ 445 | "tests/Test/AbstractFixerTestCase.php", 446 | "tests/Test/AbstractIntegrationCaseFactory.php", 447 | "tests/Test/AbstractIntegrationTestCase.php", 448 | "tests/Test/Assert/AssertTokensTrait.php", 449 | "tests/Test/IntegrationCase.php", 450 | "tests/Test/IntegrationCaseFactory.php", 451 | "tests/Test/IntegrationCaseFactoryInterface.php", 452 | "tests/Test/InternalIntegrationCaseFactory.php", 453 | "tests/Test/IsIdenticalConstraint.php", 454 | "tests/TestCase.php" 455 | ] 456 | }, 457 | "notification-url": "https://packagist.org/downloads/", 458 | "license": [ 459 | "MIT" 460 | ], 461 | "authors": [ 462 | { 463 | "name": "Fabien Potencier", 464 | "email": "fabien@symfony.com" 465 | }, 466 | { 467 | "name": "Dariusz Rumiński", 468 | "email": "dariusz.ruminski@gmail.com" 469 | } 470 | ], 471 | "description": "A tool to automatically fix PHP code style", 472 | "support": { 473 | "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", 474 | "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v2.16.7" 475 | }, 476 | "funding": [ 477 | { 478 | "url": "https://github.com/keradus", 479 | "type": "github" 480 | } 481 | ], 482 | "time": "2020-10-27T22:44:27+00:00" 483 | }, 484 | { 485 | "name": "myclabs/deep-copy", 486 | "version": "1.10.1", 487 | "source": { 488 | "type": "git", 489 | "url": "https://github.com/myclabs/DeepCopy.git", 490 | "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" 491 | }, 492 | "dist": { 493 | "type": "zip", 494 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", 495 | "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", 496 | "shasum": "" 497 | }, 498 | "require": { 499 | "php": "^7.1 || ^8.0" 500 | }, 501 | "replace": { 502 | "myclabs/deep-copy": "self.version" 503 | }, 504 | "require-dev": { 505 | "doctrine/collections": "^1.0", 506 | "doctrine/common": "^2.6", 507 | "phpunit/phpunit": "^7.1" 508 | }, 509 | "type": "library", 510 | "autoload": { 511 | "psr-4": { 512 | "DeepCopy\\": "src/DeepCopy/" 513 | }, 514 | "files": [ 515 | "src/DeepCopy/deep_copy.php" 516 | ] 517 | }, 518 | "notification-url": "https://packagist.org/downloads/", 519 | "license": [ 520 | "MIT" 521 | ], 522 | "description": "Create deep copies (clones) of your objects", 523 | "keywords": [ 524 | "clone", 525 | "copy", 526 | "duplicate", 527 | "object", 528 | "object graph" 529 | ], 530 | "support": { 531 | "issues": "https://github.com/myclabs/DeepCopy/issues", 532 | "source": "https://github.com/myclabs/DeepCopy/tree/1.x" 533 | }, 534 | "funding": [ 535 | { 536 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", 537 | "type": "tidelift" 538 | } 539 | ], 540 | "time": "2020-06-29T13:22:24+00:00" 541 | }, 542 | { 543 | "name": "nikic/php-parser", 544 | "version": "v4.10.2", 545 | "source": { 546 | "type": "git", 547 | "url": "https://github.com/nikic/PHP-Parser.git", 548 | "reference": "658f1be311a230e0907f5dfe0213742aff0596de" 549 | }, 550 | "dist": { 551 | "type": "zip", 552 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/658f1be311a230e0907f5dfe0213742aff0596de", 553 | "reference": "658f1be311a230e0907f5dfe0213742aff0596de", 554 | "shasum": "" 555 | }, 556 | "require": { 557 | "ext-tokenizer": "*", 558 | "php": ">=7.0" 559 | }, 560 | "require-dev": { 561 | "ircmaxell/php-yacc": "^0.0.7", 562 | "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" 563 | }, 564 | "bin": [ 565 | "bin/php-parse" 566 | ], 567 | "type": "library", 568 | "extra": { 569 | "branch-alias": { 570 | "dev-master": "4.9-dev" 571 | } 572 | }, 573 | "autoload": { 574 | "psr-4": { 575 | "PhpParser\\": "lib/PhpParser" 576 | } 577 | }, 578 | "notification-url": "https://packagist.org/downloads/", 579 | "license": [ 580 | "BSD-3-Clause" 581 | ], 582 | "authors": [ 583 | { 584 | "name": "Nikita Popov" 585 | } 586 | ], 587 | "description": "A PHP parser written in PHP", 588 | "keywords": [ 589 | "parser", 590 | "php" 591 | ], 592 | "support": { 593 | "issues": "https://github.com/nikic/PHP-Parser/issues", 594 | "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.2" 595 | }, 596 | "time": "2020-09-26T10:30:38+00:00" 597 | }, 598 | { 599 | "name": "phar-io/manifest", 600 | "version": "2.0.1", 601 | "source": { 602 | "type": "git", 603 | "url": "https://github.com/phar-io/manifest.git", 604 | "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" 605 | }, 606 | "dist": { 607 | "type": "zip", 608 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", 609 | "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", 610 | "shasum": "" 611 | }, 612 | "require": { 613 | "ext-dom": "*", 614 | "ext-phar": "*", 615 | "ext-xmlwriter": "*", 616 | "phar-io/version": "^3.0.1", 617 | "php": "^7.2 || ^8.0" 618 | }, 619 | "type": "library", 620 | "extra": { 621 | "branch-alias": { 622 | "dev-master": "2.0.x-dev" 623 | } 624 | }, 625 | "autoload": { 626 | "classmap": [ 627 | "src/" 628 | ] 629 | }, 630 | "notification-url": "https://packagist.org/downloads/", 631 | "license": [ 632 | "BSD-3-Clause" 633 | ], 634 | "authors": [ 635 | { 636 | "name": "Arne Blankerts", 637 | "email": "arne@blankerts.de", 638 | "role": "Developer" 639 | }, 640 | { 641 | "name": "Sebastian Heuer", 642 | "email": "sebastian@phpeople.de", 643 | "role": "Developer" 644 | }, 645 | { 646 | "name": "Sebastian Bergmann", 647 | "email": "sebastian@phpunit.de", 648 | "role": "Developer" 649 | } 650 | ], 651 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 652 | "support": { 653 | "issues": "https://github.com/phar-io/manifest/issues", 654 | "source": "https://github.com/phar-io/manifest/tree/master" 655 | }, 656 | "time": "2020-06-27T14:33:11+00:00" 657 | }, 658 | { 659 | "name": "phar-io/version", 660 | "version": "3.0.2", 661 | "source": { 662 | "type": "git", 663 | "url": "https://github.com/phar-io/version.git", 664 | "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0" 665 | }, 666 | "dist": { 667 | "type": "zip", 668 | "url": "https://api.github.com/repos/phar-io/version/zipball/c6bb6825def89e0a32220f88337f8ceaf1975fa0", 669 | "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0", 670 | "shasum": "" 671 | }, 672 | "require": { 673 | "php": "^7.2 || ^8.0" 674 | }, 675 | "type": "library", 676 | "autoload": { 677 | "classmap": [ 678 | "src/" 679 | ] 680 | }, 681 | "notification-url": "https://packagist.org/downloads/", 682 | "license": [ 683 | "BSD-3-Clause" 684 | ], 685 | "authors": [ 686 | { 687 | "name": "Arne Blankerts", 688 | "email": "arne@blankerts.de", 689 | "role": "Developer" 690 | }, 691 | { 692 | "name": "Sebastian Heuer", 693 | "email": "sebastian@phpeople.de", 694 | "role": "Developer" 695 | }, 696 | { 697 | "name": "Sebastian Bergmann", 698 | "email": "sebastian@phpunit.de", 699 | "role": "Developer" 700 | } 701 | ], 702 | "description": "Library for handling version information and constraints", 703 | "support": { 704 | "issues": "https://github.com/phar-io/version/issues", 705 | "source": "https://github.com/phar-io/version/tree/master" 706 | }, 707 | "time": "2020-06-27T14:39:04+00:00" 708 | }, 709 | { 710 | "name": "php-cs-fixer/diff", 711 | "version": "v1.3.1", 712 | "source": { 713 | "type": "git", 714 | "url": "https://github.com/PHP-CS-Fixer/diff.git", 715 | "reference": "dbd31aeb251639ac0b9e7e29405c1441907f5759" 716 | }, 717 | "dist": { 718 | "type": "zip", 719 | "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/dbd31aeb251639ac0b9e7e29405c1441907f5759", 720 | "reference": "dbd31aeb251639ac0b9e7e29405c1441907f5759", 721 | "shasum": "" 722 | }, 723 | "require": { 724 | "php": "^5.6 || ^7.0 || ^8.0" 725 | }, 726 | "require-dev": { 727 | "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", 728 | "symfony/process": "^3.3" 729 | }, 730 | "type": "library", 731 | "autoload": { 732 | "classmap": [ 733 | "src/" 734 | ] 735 | }, 736 | "notification-url": "https://packagist.org/downloads/", 737 | "license": [ 738 | "BSD-3-Clause" 739 | ], 740 | "authors": [ 741 | { 742 | "name": "Sebastian Bergmann", 743 | "email": "sebastian@phpunit.de" 744 | }, 745 | { 746 | "name": "Kore Nordmann", 747 | "email": "mail@kore-nordmann.de" 748 | }, 749 | { 750 | "name": "SpacePossum" 751 | } 752 | ], 753 | "description": "sebastian/diff v2 backport support for PHP5.6", 754 | "homepage": "https://github.com/PHP-CS-Fixer", 755 | "keywords": [ 756 | "diff" 757 | ], 758 | "support": { 759 | "issues": "https://github.com/PHP-CS-Fixer/diff/issues", 760 | "source": "https://github.com/PHP-CS-Fixer/diff/tree/v1.3.1" 761 | }, 762 | "time": "2020-10-14T08:39:05+00:00" 763 | }, 764 | { 765 | "name": "phpdocumentor/reflection-common", 766 | "version": "2.2.0", 767 | "source": { 768 | "type": "git", 769 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 770 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" 771 | }, 772 | "dist": { 773 | "type": "zip", 774 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", 775 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", 776 | "shasum": "" 777 | }, 778 | "require": { 779 | "php": "^7.2 || ^8.0" 780 | }, 781 | "type": "library", 782 | "extra": { 783 | "branch-alias": { 784 | "dev-2.x": "2.x-dev" 785 | } 786 | }, 787 | "autoload": { 788 | "psr-4": { 789 | "phpDocumentor\\Reflection\\": "src/" 790 | } 791 | }, 792 | "notification-url": "https://packagist.org/downloads/", 793 | "license": [ 794 | "MIT" 795 | ], 796 | "authors": [ 797 | { 798 | "name": "Jaap van Otterdijk", 799 | "email": "opensource@ijaap.nl" 800 | } 801 | ], 802 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 803 | "homepage": "http://www.phpdoc.org", 804 | "keywords": [ 805 | "FQSEN", 806 | "phpDocumentor", 807 | "phpdoc", 808 | "reflection", 809 | "static analysis" 810 | ], 811 | "support": { 812 | "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", 813 | "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" 814 | }, 815 | "time": "2020-06-27T09:03:43+00:00" 816 | }, 817 | { 818 | "name": "phpdocumentor/reflection-docblock", 819 | "version": "5.2.2", 820 | "source": { 821 | "type": "git", 822 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 823 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" 824 | }, 825 | "dist": { 826 | "type": "zip", 827 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", 828 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", 829 | "shasum": "" 830 | }, 831 | "require": { 832 | "ext-filter": "*", 833 | "php": "^7.2 || ^8.0", 834 | "phpdocumentor/reflection-common": "^2.2", 835 | "phpdocumentor/type-resolver": "^1.3", 836 | "webmozart/assert": "^1.9.1" 837 | }, 838 | "require-dev": { 839 | "mockery/mockery": "~1.3.2" 840 | }, 841 | "type": "library", 842 | "extra": { 843 | "branch-alias": { 844 | "dev-master": "5.x-dev" 845 | } 846 | }, 847 | "autoload": { 848 | "psr-4": { 849 | "phpDocumentor\\Reflection\\": "src" 850 | } 851 | }, 852 | "notification-url": "https://packagist.org/downloads/", 853 | "license": [ 854 | "MIT" 855 | ], 856 | "authors": [ 857 | { 858 | "name": "Mike van Riel", 859 | "email": "me@mikevanriel.com" 860 | }, 861 | { 862 | "name": "Jaap van Otterdijk", 863 | "email": "account@ijaap.nl" 864 | } 865 | ], 866 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 867 | "support": { 868 | "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", 869 | "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" 870 | }, 871 | "time": "2020-09-03T19:13:55+00:00" 872 | }, 873 | { 874 | "name": "phpdocumentor/type-resolver", 875 | "version": "1.4.0", 876 | "source": { 877 | "type": "git", 878 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 879 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" 880 | }, 881 | "dist": { 882 | "type": "zip", 883 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", 884 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", 885 | "shasum": "" 886 | }, 887 | "require": { 888 | "php": "^7.2 || ^8.0", 889 | "phpdocumentor/reflection-common": "^2.0" 890 | }, 891 | "require-dev": { 892 | "ext-tokenizer": "*" 893 | }, 894 | "type": "library", 895 | "extra": { 896 | "branch-alias": { 897 | "dev-1.x": "1.x-dev" 898 | } 899 | }, 900 | "autoload": { 901 | "psr-4": { 902 | "phpDocumentor\\Reflection\\": "src" 903 | } 904 | }, 905 | "notification-url": "https://packagist.org/downloads/", 906 | "license": [ 907 | "MIT" 908 | ], 909 | "authors": [ 910 | { 911 | "name": "Mike van Riel", 912 | "email": "me@mikevanriel.com" 913 | } 914 | ], 915 | "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", 916 | "support": { 917 | "issues": "https://github.com/phpDocumentor/TypeResolver/issues", 918 | "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" 919 | }, 920 | "time": "2020-09-17T18:55:26+00:00" 921 | }, 922 | { 923 | "name": "phpspec/prophecy", 924 | "version": "1.12.1", 925 | "source": { 926 | "type": "git", 927 | "url": "https://github.com/phpspec/prophecy.git", 928 | "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" 929 | }, 930 | "dist": { 931 | "type": "zip", 932 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", 933 | "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", 934 | "shasum": "" 935 | }, 936 | "require": { 937 | "doctrine/instantiator": "^1.2", 938 | "php": "^7.2 || ~8.0, <8.1", 939 | "phpdocumentor/reflection-docblock": "^5.2", 940 | "sebastian/comparator": "^3.0 || ^4.0", 941 | "sebastian/recursion-context": "^3.0 || ^4.0" 942 | }, 943 | "require-dev": { 944 | "phpspec/phpspec": "^6.0", 945 | "phpunit/phpunit": "^8.0 || ^9.0 <9.3" 946 | }, 947 | "type": "library", 948 | "extra": { 949 | "branch-alias": { 950 | "dev-master": "1.11.x-dev" 951 | } 952 | }, 953 | "autoload": { 954 | "psr-4": { 955 | "Prophecy\\": "src/Prophecy" 956 | } 957 | }, 958 | "notification-url": "https://packagist.org/downloads/", 959 | "license": [ 960 | "MIT" 961 | ], 962 | "authors": [ 963 | { 964 | "name": "Konstantin Kudryashov", 965 | "email": "ever.zet@gmail.com", 966 | "homepage": "http://everzet.com" 967 | }, 968 | { 969 | "name": "Marcello Duarte", 970 | "email": "marcello.duarte@gmail.com" 971 | } 972 | ], 973 | "description": "Highly opinionated mocking framework for PHP 5.3+", 974 | "homepage": "https://github.com/phpspec/prophecy", 975 | "keywords": [ 976 | "Double", 977 | "Dummy", 978 | "fake", 979 | "mock", 980 | "spy", 981 | "stub" 982 | ], 983 | "support": { 984 | "issues": "https://github.com/phpspec/prophecy/issues", 985 | "source": "https://github.com/phpspec/prophecy/tree/1.12.1" 986 | }, 987 | "time": "2020-09-29T09:10:42+00:00" 988 | }, 989 | { 990 | "name": "phpunit/php-code-coverage", 991 | "version": "9.2.3", 992 | "source": { 993 | "type": "git", 994 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 995 | "reference": "6b20e2055f7c29b56cb3870b3de7cc463d7add41" 996 | }, 997 | "dist": { 998 | "type": "zip", 999 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6b20e2055f7c29b56cb3870b3de7cc463d7add41", 1000 | "reference": "6b20e2055f7c29b56cb3870b3de7cc463d7add41", 1001 | "shasum": "" 1002 | }, 1003 | "require": { 1004 | "ext-dom": "*", 1005 | "ext-libxml": "*", 1006 | "ext-xmlwriter": "*", 1007 | "nikic/php-parser": "^4.10.2", 1008 | "php": ">=7.3", 1009 | "phpunit/php-file-iterator": "^3.0.3", 1010 | "phpunit/php-text-template": "^2.0.2", 1011 | "sebastian/code-unit-reverse-lookup": "^2.0.2", 1012 | "sebastian/complexity": "^2.0", 1013 | "sebastian/environment": "^5.1.2", 1014 | "sebastian/lines-of-code": "^1.0", 1015 | "sebastian/version": "^3.0.1", 1016 | "theseer/tokenizer": "^1.2.0" 1017 | }, 1018 | "require-dev": { 1019 | "phpunit/phpunit": "^9.3" 1020 | }, 1021 | "suggest": { 1022 | "ext-pcov": "*", 1023 | "ext-xdebug": "*" 1024 | }, 1025 | "type": "library", 1026 | "extra": { 1027 | "branch-alias": { 1028 | "dev-master": "9.2-dev" 1029 | } 1030 | }, 1031 | "autoload": { 1032 | "classmap": [ 1033 | "src/" 1034 | ] 1035 | }, 1036 | "notification-url": "https://packagist.org/downloads/", 1037 | "license": [ 1038 | "BSD-3-Clause" 1039 | ], 1040 | "authors": [ 1041 | { 1042 | "name": "Sebastian Bergmann", 1043 | "email": "sebastian@phpunit.de", 1044 | "role": "lead" 1045 | } 1046 | ], 1047 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 1048 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 1049 | "keywords": [ 1050 | "coverage", 1051 | "testing", 1052 | "xunit" 1053 | ], 1054 | "support": { 1055 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", 1056 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.3" 1057 | }, 1058 | "funding": [ 1059 | { 1060 | "url": "https://github.com/sebastianbergmann", 1061 | "type": "github" 1062 | } 1063 | ], 1064 | "time": "2020-10-30T10:46:41+00:00" 1065 | }, 1066 | { 1067 | "name": "phpunit/php-file-iterator", 1068 | "version": "3.0.5", 1069 | "source": { 1070 | "type": "git", 1071 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 1072 | "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" 1073 | }, 1074 | "dist": { 1075 | "type": "zip", 1076 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", 1077 | "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", 1078 | "shasum": "" 1079 | }, 1080 | "require": { 1081 | "php": ">=7.3" 1082 | }, 1083 | "require-dev": { 1084 | "phpunit/phpunit": "^9.3" 1085 | }, 1086 | "type": "library", 1087 | "extra": { 1088 | "branch-alias": { 1089 | "dev-master": "3.0-dev" 1090 | } 1091 | }, 1092 | "autoload": { 1093 | "classmap": [ 1094 | "src/" 1095 | ] 1096 | }, 1097 | "notification-url": "https://packagist.org/downloads/", 1098 | "license": [ 1099 | "BSD-3-Clause" 1100 | ], 1101 | "authors": [ 1102 | { 1103 | "name": "Sebastian Bergmann", 1104 | "email": "sebastian@phpunit.de", 1105 | "role": "lead" 1106 | } 1107 | ], 1108 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 1109 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 1110 | "keywords": [ 1111 | "filesystem", 1112 | "iterator" 1113 | ], 1114 | "support": { 1115 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", 1116 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" 1117 | }, 1118 | "funding": [ 1119 | { 1120 | "url": "https://github.com/sebastianbergmann", 1121 | "type": "github" 1122 | } 1123 | ], 1124 | "time": "2020-09-28T05:57:25+00:00" 1125 | }, 1126 | { 1127 | "name": "phpunit/php-invoker", 1128 | "version": "3.1.1", 1129 | "source": { 1130 | "type": "git", 1131 | "url": "https://github.com/sebastianbergmann/php-invoker.git", 1132 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" 1133 | }, 1134 | "dist": { 1135 | "type": "zip", 1136 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", 1137 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", 1138 | "shasum": "" 1139 | }, 1140 | "require": { 1141 | "php": ">=7.3" 1142 | }, 1143 | "require-dev": { 1144 | "ext-pcntl": "*", 1145 | "phpunit/phpunit": "^9.3" 1146 | }, 1147 | "suggest": { 1148 | "ext-pcntl": "*" 1149 | }, 1150 | "type": "library", 1151 | "extra": { 1152 | "branch-alias": { 1153 | "dev-master": "3.1-dev" 1154 | } 1155 | }, 1156 | "autoload": { 1157 | "classmap": [ 1158 | "src/" 1159 | ] 1160 | }, 1161 | "notification-url": "https://packagist.org/downloads/", 1162 | "license": [ 1163 | "BSD-3-Clause" 1164 | ], 1165 | "authors": [ 1166 | { 1167 | "name": "Sebastian Bergmann", 1168 | "email": "sebastian@phpunit.de", 1169 | "role": "lead" 1170 | } 1171 | ], 1172 | "description": "Invoke callables with a timeout", 1173 | "homepage": "https://github.com/sebastianbergmann/php-invoker/", 1174 | "keywords": [ 1175 | "process" 1176 | ], 1177 | "support": { 1178 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues", 1179 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" 1180 | }, 1181 | "funding": [ 1182 | { 1183 | "url": "https://github.com/sebastianbergmann", 1184 | "type": "github" 1185 | } 1186 | ], 1187 | "time": "2020-09-28T05:58:55+00:00" 1188 | }, 1189 | { 1190 | "name": "phpunit/php-text-template", 1191 | "version": "2.0.4", 1192 | "source": { 1193 | "type": "git", 1194 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 1195 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" 1196 | }, 1197 | "dist": { 1198 | "type": "zip", 1199 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", 1200 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", 1201 | "shasum": "" 1202 | }, 1203 | "require": { 1204 | "php": ">=7.3" 1205 | }, 1206 | "require-dev": { 1207 | "phpunit/phpunit": "^9.3" 1208 | }, 1209 | "type": "library", 1210 | "extra": { 1211 | "branch-alias": { 1212 | "dev-master": "2.0-dev" 1213 | } 1214 | }, 1215 | "autoload": { 1216 | "classmap": [ 1217 | "src/" 1218 | ] 1219 | }, 1220 | "notification-url": "https://packagist.org/downloads/", 1221 | "license": [ 1222 | "BSD-3-Clause" 1223 | ], 1224 | "authors": [ 1225 | { 1226 | "name": "Sebastian Bergmann", 1227 | "email": "sebastian@phpunit.de", 1228 | "role": "lead" 1229 | } 1230 | ], 1231 | "description": "Simple template engine.", 1232 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 1233 | "keywords": [ 1234 | "template" 1235 | ], 1236 | "support": { 1237 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues", 1238 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" 1239 | }, 1240 | "funding": [ 1241 | { 1242 | "url": "https://github.com/sebastianbergmann", 1243 | "type": "github" 1244 | } 1245 | ], 1246 | "time": "2020-10-26T05:33:50+00:00" 1247 | }, 1248 | { 1249 | "name": "phpunit/php-timer", 1250 | "version": "5.0.3", 1251 | "source": { 1252 | "type": "git", 1253 | "url": "https://github.com/sebastianbergmann/php-timer.git", 1254 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" 1255 | }, 1256 | "dist": { 1257 | "type": "zip", 1258 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", 1259 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", 1260 | "shasum": "" 1261 | }, 1262 | "require": { 1263 | "php": ">=7.3" 1264 | }, 1265 | "require-dev": { 1266 | "phpunit/phpunit": "^9.3" 1267 | }, 1268 | "type": "library", 1269 | "extra": { 1270 | "branch-alias": { 1271 | "dev-master": "5.0-dev" 1272 | } 1273 | }, 1274 | "autoload": { 1275 | "classmap": [ 1276 | "src/" 1277 | ] 1278 | }, 1279 | "notification-url": "https://packagist.org/downloads/", 1280 | "license": [ 1281 | "BSD-3-Clause" 1282 | ], 1283 | "authors": [ 1284 | { 1285 | "name": "Sebastian Bergmann", 1286 | "email": "sebastian@phpunit.de", 1287 | "role": "lead" 1288 | } 1289 | ], 1290 | "description": "Utility class for timing", 1291 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 1292 | "keywords": [ 1293 | "timer" 1294 | ], 1295 | "support": { 1296 | "issues": "https://github.com/sebastianbergmann/php-timer/issues", 1297 | "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" 1298 | }, 1299 | "funding": [ 1300 | { 1301 | "url": "https://github.com/sebastianbergmann", 1302 | "type": "github" 1303 | } 1304 | ], 1305 | "time": "2020-10-26T13:16:10+00:00" 1306 | }, 1307 | { 1308 | "name": "phpunit/phpunit", 1309 | "version": "9.4.2", 1310 | "source": { 1311 | "type": "git", 1312 | "url": "https://github.com/sebastianbergmann/phpunit.git", 1313 | "reference": "3866b2eeeed21b1b099c4bc0b7a1690ac6fd5baa" 1314 | }, 1315 | "dist": { 1316 | "type": "zip", 1317 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3866b2eeeed21b1b099c4bc0b7a1690ac6fd5baa", 1318 | "reference": "3866b2eeeed21b1b099c4bc0b7a1690ac6fd5baa", 1319 | "shasum": "" 1320 | }, 1321 | "require": { 1322 | "doctrine/instantiator": "^1.3.1", 1323 | "ext-dom": "*", 1324 | "ext-json": "*", 1325 | "ext-libxml": "*", 1326 | "ext-mbstring": "*", 1327 | "ext-xml": "*", 1328 | "ext-xmlwriter": "*", 1329 | "myclabs/deep-copy": "^1.10.1", 1330 | "phar-io/manifest": "^2.0.1", 1331 | "phar-io/version": "^3.0.2", 1332 | "php": ">=7.3", 1333 | "phpspec/prophecy": "^1.12.1", 1334 | "phpunit/php-code-coverage": "^9.2", 1335 | "phpunit/php-file-iterator": "^3.0.5", 1336 | "phpunit/php-invoker": "^3.1.1", 1337 | "phpunit/php-text-template": "^2.0.3", 1338 | "phpunit/php-timer": "^5.0.2", 1339 | "sebastian/cli-parser": "^1.0.1", 1340 | "sebastian/code-unit": "^1.0.6", 1341 | "sebastian/comparator": "^4.0.5", 1342 | "sebastian/diff": "^4.0.3", 1343 | "sebastian/environment": "^5.1.3", 1344 | "sebastian/exporter": "^4.0.3", 1345 | "sebastian/global-state": "^5.0.1", 1346 | "sebastian/object-enumerator": "^4.0.3", 1347 | "sebastian/resource-operations": "^3.0.3", 1348 | "sebastian/type": "^2.3", 1349 | "sebastian/version": "^3.0.2" 1350 | }, 1351 | "require-dev": { 1352 | "ext-pdo": "*", 1353 | "phpspec/prophecy-phpunit": "^2.0.1" 1354 | }, 1355 | "suggest": { 1356 | "ext-soap": "*", 1357 | "ext-xdebug": "*" 1358 | }, 1359 | "bin": [ 1360 | "phpunit" 1361 | ], 1362 | "type": "library", 1363 | "extra": { 1364 | "branch-alias": { 1365 | "dev-master": "9.4-dev" 1366 | } 1367 | }, 1368 | "autoload": { 1369 | "classmap": [ 1370 | "src/" 1371 | ], 1372 | "files": [ 1373 | "src/Framework/Assert/Functions.php" 1374 | ] 1375 | }, 1376 | "notification-url": "https://packagist.org/downloads/", 1377 | "license": [ 1378 | "BSD-3-Clause" 1379 | ], 1380 | "authors": [ 1381 | { 1382 | "name": "Sebastian Bergmann", 1383 | "email": "sebastian@phpunit.de", 1384 | "role": "lead" 1385 | } 1386 | ], 1387 | "description": "The PHP Unit Testing framework.", 1388 | "homepage": "https://phpunit.de/", 1389 | "keywords": [ 1390 | "phpunit", 1391 | "testing", 1392 | "xunit" 1393 | ], 1394 | "support": { 1395 | "issues": "https://github.com/sebastianbergmann/phpunit/issues", 1396 | "source": "https://github.com/sebastianbergmann/phpunit/tree/9.4.2" 1397 | }, 1398 | "funding": [ 1399 | { 1400 | "url": "https://phpunit.de/donate.html", 1401 | "type": "custom" 1402 | }, 1403 | { 1404 | "url": "https://github.com/sebastianbergmann", 1405 | "type": "github" 1406 | } 1407 | ], 1408 | "time": "2020-10-19T09:23:29+00:00" 1409 | }, 1410 | { 1411 | "name": "predis/predis", 1412 | "version": "v1.1.6", 1413 | "source": { 1414 | "type": "git", 1415 | "url": "https://github.com/predis/predis.git", 1416 | "reference": "9930e933c67446962997b05201c69c2319bf26de" 1417 | }, 1418 | "dist": { 1419 | "type": "zip", 1420 | "url": "https://api.github.com/repos/predis/predis/zipball/9930e933c67446962997b05201c69c2319bf26de", 1421 | "reference": "9930e933c67446962997b05201c69c2319bf26de", 1422 | "shasum": "" 1423 | }, 1424 | "require": { 1425 | "php": ">=5.3.9" 1426 | }, 1427 | "require-dev": { 1428 | "cweagans/composer-patches": "^1.6", 1429 | "phpunit/phpunit": "~4.8" 1430 | }, 1431 | "suggest": { 1432 | "ext-curl": "Allows access to Webdis when paired with phpiredis", 1433 | "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" 1434 | }, 1435 | "type": "library", 1436 | "extra": { 1437 | "composer-exit-on-patch-failure": true, 1438 | "patches": { 1439 | "phpunit/phpunit-mock-objects": { 1440 | "Fix PHP 7 and 8 compatibility": "./tests/phpunit_mock_objects.patch" 1441 | }, 1442 | "phpunit/phpunit": { 1443 | "Fix PHP 7 compatibility": "./tests/phpunit_php7.patch", 1444 | "Fix PHP 8 compatibility": "./tests/phpunit_php8.patch" 1445 | } 1446 | } 1447 | }, 1448 | "autoload": { 1449 | "psr-4": { 1450 | "Predis\\": "src/" 1451 | } 1452 | }, 1453 | "notification-url": "https://packagist.org/downloads/", 1454 | "license": [ 1455 | "MIT" 1456 | ], 1457 | "authors": [ 1458 | { 1459 | "name": "Daniele Alessandri", 1460 | "email": "suppakilla@gmail.com", 1461 | "homepage": "http://clorophilla.net", 1462 | "role": "Creator & Maintainer" 1463 | }, 1464 | { 1465 | "name": "Till Krüss", 1466 | "homepage": "https://till.im", 1467 | "role": "Maintainer" 1468 | } 1469 | ], 1470 | "description": "Flexible and feature-complete Redis client for PHP and HHVM", 1471 | "homepage": "http://github.com/predis/predis", 1472 | "keywords": [ 1473 | "nosql", 1474 | "predis", 1475 | "redis" 1476 | ], 1477 | "support": { 1478 | "issues": "https://github.com/predis/predis/issues", 1479 | "source": "https://github.com/predis/predis/tree/v1.1.6" 1480 | }, 1481 | "funding": [ 1482 | { 1483 | "url": "https://github.com/sponsors/tillkruss", 1484 | "type": "github" 1485 | } 1486 | ], 1487 | "time": "2020-09-11T19:18:05+00:00" 1488 | }, 1489 | { 1490 | "name": "psr/container", 1491 | "version": "1.0.0", 1492 | "source": { 1493 | "type": "git", 1494 | "url": "https://github.com/php-fig/container.git", 1495 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" 1496 | }, 1497 | "dist": { 1498 | "type": "zip", 1499 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 1500 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 1501 | "shasum": "" 1502 | }, 1503 | "require": { 1504 | "php": ">=5.3.0" 1505 | }, 1506 | "type": "library", 1507 | "extra": { 1508 | "branch-alias": { 1509 | "dev-master": "1.0.x-dev" 1510 | } 1511 | }, 1512 | "autoload": { 1513 | "psr-4": { 1514 | "Psr\\Container\\": "src/" 1515 | } 1516 | }, 1517 | "notification-url": "https://packagist.org/downloads/", 1518 | "license": [ 1519 | "MIT" 1520 | ], 1521 | "authors": [ 1522 | { 1523 | "name": "PHP-FIG", 1524 | "homepage": "http://www.php-fig.org/" 1525 | } 1526 | ], 1527 | "description": "Common Container Interface (PHP FIG PSR-11)", 1528 | "homepage": "https://github.com/php-fig/container", 1529 | "keywords": [ 1530 | "PSR-11", 1531 | "container", 1532 | "container-interface", 1533 | "container-interop", 1534 | "psr" 1535 | ], 1536 | "support": { 1537 | "issues": "https://github.com/php-fig/container/issues", 1538 | "source": "https://github.com/php-fig/container/tree/master" 1539 | }, 1540 | "time": "2017-02-14T16:28:37+00:00" 1541 | }, 1542 | { 1543 | "name": "psr/event-dispatcher", 1544 | "version": "1.0.0", 1545 | "source": { 1546 | "type": "git", 1547 | "url": "https://github.com/php-fig/event-dispatcher.git", 1548 | "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" 1549 | }, 1550 | "dist": { 1551 | "type": "zip", 1552 | "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", 1553 | "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", 1554 | "shasum": "" 1555 | }, 1556 | "require": { 1557 | "php": ">=7.2.0" 1558 | }, 1559 | "type": "library", 1560 | "extra": { 1561 | "branch-alias": { 1562 | "dev-master": "1.0.x-dev" 1563 | } 1564 | }, 1565 | "autoload": { 1566 | "psr-4": { 1567 | "Psr\\EventDispatcher\\": "src/" 1568 | } 1569 | }, 1570 | "notification-url": "https://packagist.org/downloads/", 1571 | "license": [ 1572 | "MIT" 1573 | ], 1574 | "authors": [ 1575 | { 1576 | "name": "PHP-FIG", 1577 | "homepage": "http://www.php-fig.org/" 1578 | } 1579 | ], 1580 | "description": "Standard interfaces for event handling.", 1581 | "keywords": [ 1582 | "events", 1583 | "psr", 1584 | "psr-14" 1585 | ], 1586 | "support": { 1587 | "issues": "https://github.com/php-fig/event-dispatcher/issues", 1588 | "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" 1589 | }, 1590 | "time": "2019-01-08T18:20:26+00:00" 1591 | }, 1592 | { 1593 | "name": "psr/log", 1594 | "version": "1.1.3", 1595 | "source": { 1596 | "type": "git", 1597 | "url": "https://github.com/php-fig/log.git", 1598 | "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" 1599 | }, 1600 | "dist": { 1601 | "type": "zip", 1602 | "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", 1603 | "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", 1604 | "shasum": "" 1605 | }, 1606 | "require": { 1607 | "php": ">=5.3.0" 1608 | }, 1609 | "type": "library", 1610 | "extra": { 1611 | "branch-alias": { 1612 | "dev-master": "1.1.x-dev" 1613 | } 1614 | }, 1615 | "autoload": { 1616 | "psr-4": { 1617 | "Psr\\Log\\": "Psr/Log/" 1618 | } 1619 | }, 1620 | "notification-url": "https://packagist.org/downloads/", 1621 | "license": [ 1622 | "MIT" 1623 | ], 1624 | "authors": [ 1625 | { 1626 | "name": "PHP-FIG", 1627 | "homepage": "http://www.php-fig.org/" 1628 | } 1629 | ], 1630 | "description": "Common interface for logging libraries", 1631 | "homepage": "https://github.com/php-fig/log", 1632 | "keywords": [ 1633 | "log", 1634 | "psr", 1635 | "psr-3" 1636 | ], 1637 | "support": { 1638 | "source": "https://github.com/php-fig/log/tree/1.1.3" 1639 | }, 1640 | "time": "2020-03-23T09:12:05+00:00" 1641 | }, 1642 | { 1643 | "name": "sebastian/cli-parser", 1644 | "version": "1.0.1", 1645 | "source": { 1646 | "type": "git", 1647 | "url": "https://github.com/sebastianbergmann/cli-parser.git", 1648 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" 1649 | }, 1650 | "dist": { 1651 | "type": "zip", 1652 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", 1653 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", 1654 | "shasum": "" 1655 | }, 1656 | "require": { 1657 | "php": ">=7.3" 1658 | }, 1659 | "require-dev": { 1660 | "phpunit/phpunit": "^9.3" 1661 | }, 1662 | "type": "library", 1663 | "extra": { 1664 | "branch-alias": { 1665 | "dev-master": "1.0-dev" 1666 | } 1667 | }, 1668 | "autoload": { 1669 | "classmap": [ 1670 | "src/" 1671 | ] 1672 | }, 1673 | "notification-url": "https://packagist.org/downloads/", 1674 | "license": [ 1675 | "BSD-3-Clause" 1676 | ], 1677 | "authors": [ 1678 | { 1679 | "name": "Sebastian Bergmann", 1680 | "email": "sebastian@phpunit.de", 1681 | "role": "lead" 1682 | } 1683 | ], 1684 | "description": "Library for parsing CLI options", 1685 | "homepage": "https://github.com/sebastianbergmann/cli-parser", 1686 | "support": { 1687 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues", 1688 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" 1689 | }, 1690 | "funding": [ 1691 | { 1692 | "url": "https://github.com/sebastianbergmann", 1693 | "type": "github" 1694 | } 1695 | ], 1696 | "time": "2020-09-28T06:08:49+00:00" 1697 | }, 1698 | { 1699 | "name": "sebastian/code-unit", 1700 | "version": "1.0.8", 1701 | "source": { 1702 | "type": "git", 1703 | "url": "https://github.com/sebastianbergmann/code-unit.git", 1704 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" 1705 | }, 1706 | "dist": { 1707 | "type": "zip", 1708 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", 1709 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", 1710 | "shasum": "" 1711 | }, 1712 | "require": { 1713 | "php": ">=7.3" 1714 | }, 1715 | "require-dev": { 1716 | "phpunit/phpunit": "^9.3" 1717 | }, 1718 | "type": "library", 1719 | "extra": { 1720 | "branch-alias": { 1721 | "dev-master": "1.0-dev" 1722 | } 1723 | }, 1724 | "autoload": { 1725 | "classmap": [ 1726 | "src/" 1727 | ] 1728 | }, 1729 | "notification-url": "https://packagist.org/downloads/", 1730 | "license": [ 1731 | "BSD-3-Clause" 1732 | ], 1733 | "authors": [ 1734 | { 1735 | "name": "Sebastian Bergmann", 1736 | "email": "sebastian@phpunit.de", 1737 | "role": "lead" 1738 | } 1739 | ], 1740 | "description": "Collection of value objects that represent the PHP code units", 1741 | "homepage": "https://github.com/sebastianbergmann/code-unit", 1742 | "support": { 1743 | "issues": "https://github.com/sebastianbergmann/code-unit/issues", 1744 | "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" 1745 | }, 1746 | "funding": [ 1747 | { 1748 | "url": "https://github.com/sebastianbergmann", 1749 | "type": "github" 1750 | } 1751 | ], 1752 | "time": "2020-10-26T13:08:54+00:00" 1753 | }, 1754 | { 1755 | "name": "sebastian/code-unit-reverse-lookup", 1756 | "version": "2.0.3", 1757 | "source": { 1758 | "type": "git", 1759 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 1760 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" 1761 | }, 1762 | "dist": { 1763 | "type": "zip", 1764 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 1765 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 1766 | "shasum": "" 1767 | }, 1768 | "require": { 1769 | "php": ">=7.3" 1770 | }, 1771 | "require-dev": { 1772 | "phpunit/phpunit": "^9.3" 1773 | }, 1774 | "type": "library", 1775 | "extra": { 1776 | "branch-alias": { 1777 | "dev-master": "2.0-dev" 1778 | } 1779 | }, 1780 | "autoload": { 1781 | "classmap": [ 1782 | "src/" 1783 | ] 1784 | }, 1785 | "notification-url": "https://packagist.org/downloads/", 1786 | "license": [ 1787 | "BSD-3-Clause" 1788 | ], 1789 | "authors": [ 1790 | { 1791 | "name": "Sebastian Bergmann", 1792 | "email": "sebastian@phpunit.de" 1793 | } 1794 | ], 1795 | "description": "Looks up which function or method a line of code belongs to", 1796 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 1797 | "support": { 1798 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", 1799 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" 1800 | }, 1801 | "funding": [ 1802 | { 1803 | "url": "https://github.com/sebastianbergmann", 1804 | "type": "github" 1805 | } 1806 | ], 1807 | "time": "2020-09-28T05:30:19+00:00" 1808 | }, 1809 | { 1810 | "name": "sebastian/comparator", 1811 | "version": "4.0.6", 1812 | "source": { 1813 | "type": "git", 1814 | "url": "https://github.com/sebastianbergmann/comparator.git", 1815 | "reference": "55f4261989e546dc112258c7a75935a81a7ce382" 1816 | }, 1817 | "dist": { 1818 | "type": "zip", 1819 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", 1820 | "reference": "55f4261989e546dc112258c7a75935a81a7ce382", 1821 | "shasum": "" 1822 | }, 1823 | "require": { 1824 | "php": ">=7.3", 1825 | "sebastian/diff": "^4.0", 1826 | "sebastian/exporter": "^4.0" 1827 | }, 1828 | "require-dev": { 1829 | "phpunit/phpunit": "^9.3" 1830 | }, 1831 | "type": "library", 1832 | "extra": { 1833 | "branch-alias": { 1834 | "dev-master": "4.0-dev" 1835 | } 1836 | }, 1837 | "autoload": { 1838 | "classmap": [ 1839 | "src/" 1840 | ] 1841 | }, 1842 | "notification-url": "https://packagist.org/downloads/", 1843 | "license": [ 1844 | "BSD-3-Clause" 1845 | ], 1846 | "authors": [ 1847 | { 1848 | "name": "Sebastian Bergmann", 1849 | "email": "sebastian@phpunit.de" 1850 | }, 1851 | { 1852 | "name": "Jeff Welch", 1853 | "email": "whatthejeff@gmail.com" 1854 | }, 1855 | { 1856 | "name": "Volker Dusch", 1857 | "email": "github@wallbash.com" 1858 | }, 1859 | { 1860 | "name": "Bernhard Schussek", 1861 | "email": "bschussek@2bepublished.at" 1862 | } 1863 | ], 1864 | "description": "Provides the functionality to compare PHP values for equality", 1865 | "homepage": "https://github.com/sebastianbergmann/comparator", 1866 | "keywords": [ 1867 | "comparator", 1868 | "compare", 1869 | "equality" 1870 | ], 1871 | "support": { 1872 | "issues": "https://github.com/sebastianbergmann/comparator/issues", 1873 | "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" 1874 | }, 1875 | "funding": [ 1876 | { 1877 | "url": "https://github.com/sebastianbergmann", 1878 | "type": "github" 1879 | } 1880 | ], 1881 | "time": "2020-10-26T15:49:45+00:00" 1882 | }, 1883 | { 1884 | "name": "sebastian/complexity", 1885 | "version": "2.0.2", 1886 | "source": { 1887 | "type": "git", 1888 | "url": "https://github.com/sebastianbergmann/complexity.git", 1889 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" 1890 | }, 1891 | "dist": { 1892 | "type": "zip", 1893 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", 1894 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", 1895 | "shasum": "" 1896 | }, 1897 | "require": { 1898 | "nikic/php-parser": "^4.7", 1899 | "php": ">=7.3" 1900 | }, 1901 | "require-dev": { 1902 | "phpunit/phpunit": "^9.3" 1903 | }, 1904 | "type": "library", 1905 | "extra": { 1906 | "branch-alias": { 1907 | "dev-master": "2.0-dev" 1908 | } 1909 | }, 1910 | "autoload": { 1911 | "classmap": [ 1912 | "src/" 1913 | ] 1914 | }, 1915 | "notification-url": "https://packagist.org/downloads/", 1916 | "license": [ 1917 | "BSD-3-Clause" 1918 | ], 1919 | "authors": [ 1920 | { 1921 | "name": "Sebastian Bergmann", 1922 | "email": "sebastian@phpunit.de", 1923 | "role": "lead" 1924 | } 1925 | ], 1926 | "description": "Library for calculating the complexity of PHP code units", 1927 | "homepage": "https://github.com/sebastianbergmann/complexity", 1928 | "support": { 1929 | "issues": "https://github.com/sebastianbergmann/complexity/issues", 1930 | "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" 1931 | }, 1932 | "funding": [ 1933 | { 1934 | "url": "https://github.com/sebastianbergmann", 1935 | "type": "github" 1936 | } 1937 | ], 1938 | "time": "2020-10-26T15:52:27+00:00" 1939 | }, 1940 | { 1941 | "name": "sebastian/diff", 1942 | "version": "4.0.4", 1943 | "source": { 1944 | "type": "git", 1945 | "url": "https://github.com/sebastianbergmann/diff.git", 1946 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" 1947 | }, 1948 | "dist": { 1949 | "type": "zip", 1950 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", 1951 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", 1952 | "shasum": "" 1953 | }, 1954 | "require": { 1955 | "php": ">=7.3" 1956 | }, 1957 | "require-dev": { 1958 | "phpunit/phpunit": "^9.3", 1959 | "symfony/process": "^4.2 || ^5" 1960 | }, 1961 | "type": "library", 1962 | "extra": { 1963 | "branch-alias": { 1964 | "dev-master": "4.0-dev" 1965 | } 1966 | }, 1967 | "autoload": { 1968 | "classmap": [ 1969 | "src/" 1970 | ] 1971 | }, 1972 | "notification-url": "https://packagist.org/downloads/", 1973 | "license": [ 1974 | "BSD-3-Clause" 1975 | ], 1976 | "authors": [ 1977 | { 1978 | "name": "Sebastian Bergmann", 1979 | "email": "sebastian@phpunit.de" 1980 | }, 1981 | { 1982 | "name": "Kore Nordmann", 1983 | "email": "mail@kore-nordmann.de" 1984 | } 1985 | ], 1986 | "description": "Diff implementation", 1987 | "homepage": "https://github.com/sebastianbergmann/diff", 1988 | "keywords": [ 1989 | "diff", 1990 | "udiff", 1991 | "unidiff", 1992 | "unified diff" 1993 | ], 1994 | "support": { 1995 | "issues": "https://github.com/sebastianbergmann/diff/issues", 1996 | "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" 1997 | }, 1998 | "funding": [ 1999 | { 2000 | "url": "https://github.com/sebastianbergmann", 2001 | "type": "github" 2002 | } 2003 | ], 2004 | "time": "2020-10-26T13:10:38+00:00" 2005 | }, 2006 | { 2007 | "name": "sebastian/environment", 2008 | "version": "5.1.3", 2009 | "source": { 2010 | "type": "git", 2011 | "url": "https://github.com/sebastianbergmann/environment.git", 2012 | "reference": "388b6ced16caa751030f6a69e588299fa09200ac" 2013 | }, 2014 | "dist": { 2015 | "type": "zip", 2016 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", 2017 | "reference": "388b6ced16caa751030f6a69e588299fa09200ac", 2018 | "shasum": "" 2019 | }, 2020 | "require": { 2021 | "php": ">=7.3" 2022 | }, 2023 | "require-dev": { 2024 | "phpunit/phpunit": "^9.3" 2025 | }, 2026 | "suggest": { 2027 | "ext-posix": "*" 2028 | }, 2029 | "type": "library", 2030 | "extra": { 2031 | "branch-alias": { 2032 | "dev-master": "5.1-dev" 2033 | } 2034 | }, 2035 | "autoload": { 2036 | "classmap": [ 2037 | "src/" 2038 | ] 2039 | }, 2040 | "notification-url": "https://packagist.org/downloads/", 2041 | "license": [ 2042 | "BSD-3-Clause" 2043 | ], 2044 | "authors": [ 2045 | { 2046 | "name": "Sebastian Bergmann", 2047 | "email": "sebastian@phpunit.de" 2048 | } 2049 | ], 2050 | "description": "Provides functionality to handle HHVM/PHP environments", 2051 | "homepage": "http://www.github.com/sebastianbergmann/environment", 2052 | "keywords": [ 2053 | "Xdebug", 2054 | "environment", 2055 | "hhvm" 2056 | ], 2057 | "support": { 2058 | "issues": "https://github.com/sebastianbergmann/environment/issues", 2059 | "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" 2060 | }, 2061 | "funding": [ 2062 | { 2063 | "url": "https://github.com/sebastianbergmann", 2064 | "type": "github" 2065 | } 2066 | ], 2067 | "time": "2020-09-28T05:52:38+00:00" 2068 | }, 2069 | { 2070 | "name": "sebastian/exporter", 2071 | "version": "4.0.3", 2072 | "source": { 2073 | "type": "git", 2074 | "url": "https://github.com/sebastianbergmann/exporter.git", 2075 | "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" 2076 | }, 2077 | "dist": { 2078 | "type": "zip", 2079 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", 2080 | "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", 2081 | "shasum": "" 2082 | }, 2083 | "require": { 2084 | "php": ">=7.3", 2085 | "sebastian/recursion-context": "^4.0" 2086 | }, 2087 | "require-dev": { 2088 | "ext-mbstring": "*", 2089 | "phpunit/phpunit": "^9.3" 2090 | }, 2091 | "type": "library", 2092 | "extra": { 2093 | "branch-alias": { 2094 | "dev-master": "4.0-dev" 2095 | } 2096 | }, 2097 | "autoload": { 2098 | "classmap": [ 2099 | "src/" 2100 | ] 2101 | }, 2102 | "notification-url": "https://packagist.org/downloads/", 2103 | "license": [ 2104 | "BSD-3-Clause" 2105 | ], 2106 | "authors": [ 2107 | { 2108 | "name": "Sebastian Bergmann", 2109 | "email": "sebastian@phpunit.de" 2110 | }, 2111 | { 2112 | "name": "Jeff Welch", 2113 | "email": "whatthejeff@gmail.com" 2114 | }, 2115 | { 2116 | "name": "Volker Dusch", 2117 | "email": "github@wallbash.com" 2118 | }, 2119 | { 2120 | "name": "Adam Harvey", 2121 | "email": "aharvey@php.net" 2122 | }, 2123 | { 2124 | "name": "Bernhard Schussek", 2125 | "email": "bschussek@gmail.com" 2126 | } 2127 | ], 2128 | "description": "Provides the functionality to export PHP variables for visualization", 2129 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 2130 | "keywords": [ 2131 | "export", 2132 | "exporter" 2133 | ], 2134 | "support": { 2135 | "issues": "https://github.com/sebastianbergmann/exporter/issues", 2136 | "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" 2137 | }, 2138 | "funding": [ 2139 | { 2140 | "url": "https://github.com/sebastianbergmann", 2141 | "type": "github" 2142 | } 2143 | ], 2144 | "time": "2020-09-28T05:24:23+00:00" 2145 | }, 2146 | { 2147 | "name": "sebastian/global-state", 2148 | "version": "5.0.2", 2149 | "source": { 2150 | "type": "git", 2151 | "url": "https://github.com/sebastianbergmann/global-state.git", 2152 | "reference": "a90ccbddffa067b51f574dea6eb25d5680839455" 2153 | }, 2154 | "dist": { 2155 | "type": "zip", 2156 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455", 2157 | "reference": "a90ccbddffa067b51f574dea6eb25d5680839455", 2158 | "shasum": "" 2159 | }, 2160 | "require": { 2161 | "php": ">=7.3", 2162 | "sebastian/object-reflector": "^2.0", 2163 | "sebastian/recursion-context": "^4.0" 2164 | }, 2165 | "require-dev": { 2166 | "ext-dom": "*", 2167 | "phpunit/phpunit": "^9.3" 2168 | }, 2169 | "suggest": { 2170 | "ext-uopz": "*" 2171 | }, 2172 | "type": "library", 2173 | "extra": { 2174 | "branch-alias": { 2175 | "dev-master": "5.0-dev" 2176 | } 2177 | }, 2178 | "autoload": { 2179 | "classmap": [ 2180 | "src/" 2181 | ] 2182 | }, 2183 | "notification-url": "https://packagist.org/downloads/", 2184 | "license": [ 2185 | "BSD-3-Clause" 2186 | ], 2187 | "authors": [ 2188 | { 2189 | "name": "Sebastian Bergmann", 2190 | "email": "sebastian@phpunit.de" 2191 | } 2192 | ], 2193 | "description": "Snapshotting of global state", 2194 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 2195 | "keywords": [ 2196 | "global state" 2197 | ], 2198 | "support": { 2199 | "issues": "https://github.com/sebastianbergmann/global-state/issues", 2200 | "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2" 2201 | }, 2202 | "funding": [ 2203 | { 2204 | "url": "https://github.com/sebastianbergmann", 2205 | "type": "github" 2206 | } 2207 | ], 2208 | "time": "2020-10-26T15:55:19+00:00" 2209 | }, 2210 | { 2211 | "name": "sebastian/lines-of-code", 2212 | "version": "1.0.2", 2213 | "source": { 2214 | "type": "git", 2215 | "url": "https://github.com/sebastianbergmann/lines-of-code.git", 2216 | "reference": "acf76492a65401babcf5283296fa510782783a7a" 2217 | }, 2218 | "dist": { 2219 | "type": "zip", 2220 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/acf76492a65401babcf5283296fa510782783a7a", 2221 | "reference": "acf76492a65401babcf5283296fa510782783a7a", 2222 | "shasum": "" 2223 | }, 2224 | "require": { 2225 | "nikic/php-parser": "^4.6", 2226 | "php": ">=7.3" 2227 | }, 2228 | "require-dev": { 2229 | "phpunit/phpunit": "^9.3" 2230 | }, 2231 | "type": "library", 2232 | "extra": { 2233 | "branch-alias": { 2234 | "dev-master": "1.0-dev" 2235 | } 2236 | }, 2237 | "autoload": { 2238 | "classmap": [ 2239 | "src/" 2240 | ] 2241 | }, 2242 | "notification-url": "https://packagist.org/downloads/", 2243 | "license": [ 2244 | "BSD-3-Clause" 2245 | ], 2246 | "authors": [ 2247 | { 2248 | "name": "Sebastian Bergmann", 2249 | "email": "sebastian@phpunit.de", 2250 | "role": "lead" 2251 | } 2252 | ], 2253 | "description": "Library for counting the lines of code in PHP source code", 2254 | "homepage": "https://github.com/sebastianbergmann/lines-of-code", 2255 | "support": { 2256 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", 2257 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.2" 2258 | }, 2259 | "funding": [ 2260 | { 2261 | "url": "https://github.com/sebastianbergmann", 2262 | "type": "github" 2263 | } 2264 | ], 2265 | "time": "2020-10-26T17:03:56+00:00" 2266 | }, 2267 | { 2268 | "name": "sebastian/object-enumerator", 2269 | "version": "4.0.4", 2270 | "source": { 2271 | "type": "git", 2272 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 2273 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" 2274 | }, 2275 | "dist": { 2276 | "type": "zip", 2277 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", 2278 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", 2279 | "shasum": "" 2280 | }, 2281 | "require": { 2282 | "php": ">=7.3", 2283 | "sebastian/object-reflector": "^2.0", 2284 | "sebastian/recursion-context": "^4.0" 2285 | }, 2286 | "require-dev": { 2287 | "phpunit/phpunit": "^9.3" 2288 | }, 2289 | "type": "library", 2290 | "extra": { 2291 | "branch-alias": { 2292 | "dev-master": "4.0-dev" 2293 | } 2294 | }, 2295 | "autoload": { 2296 | "classmap": [ 2297 | "src/" 2298 | ] 2299 | }, 2300 | "notification-url": "https://packagist.org/downloads/", 2301 | "license": [ 2302 | "BSD-3-Clause" 2303 | ], 2304 | "authors": [ 2305 | { 2306 | "name": "Sebastian Bergmann", 2307 | "email": "sebastian@phpunit.de" 2308 | } 2309 | ], 2310 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 2311 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 2312 | "support": { 2313 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", 2314 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" 2315 | }, 2316 | "funding": [ 2317 | { 2318 | "url": "https://github.com/sebastianbergmann", 2319 | "type": "github" 2320 | } 2321 | ], 2322 | "time": "2020-10-26T13:12:34+00:00" 2323 | }, 2324 | { 2325 | "name": "sebastian/object-reflector", 2326 | "version": "2.0.4", 2327 | "source": { 2328 | "type": "git", 2329 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 2330 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" 2331 | }, 2332 | "dist": { 2333 | "type": "zip", 2334 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", 2335 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", 2336 | "shasum": "" 2337 | }, 2338 | "require": { 2339 | "php": ">=7.3" 2340 | }, 2341 | "require-dev": { 2342 | "phpunit/phpunit": "^9.3" 2343 | }, 2344 | "type": "library", 2345 | "extra": { 2346 | "branch-alias": { 2347 | "dev-master": "2.0-dev" 2348 | } 2349 | }, 2350 | "autoload": { 2351 | "classmap": [ 2352 | "src/" 2353 | ] 2354 | }, 2355 | "notification-url": "https://packagist.org/downloads/", 2356 | "license": [ 2357 | "BSD-3-Clause" 2358 | ], 2359 | "authors": [ 2360 | { 2361 | "name": "Sebastian Bergmann", 2362 | "email": "sebastian@phpunit.de" 2363 | } 2364 | ], 2365 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 2366 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 2367 | "support": { 2368 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues", 2369 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" 2370 | }, 2371 | "funding": [ 2372 | { 2373 | "url": "https://github.com/sebastianbergmann", 2374 | "type": "github" 2375 | } 2376 | ], 2377 | "time": "2020-10-26T13:14:26+00:00" 2378 | }, 2379 | { 2380 | "name": "sebastian/recursion-context", 2381 | "version": "4.0.4", 2382 | "source": { 2383 | "type": "git", 2384 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 2385 | "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" 2386 | }, 2387 | "dist": { 2388 | "type": "zip", 2389 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", 2390 | "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", 2391 | "shasum": "" 2392 | }, 2393 | "require": { 2394 | "php": ">=7.3" 2395 | }, 2396 | "require-dev": { 2397 | "phpunit/phpunit": "^9.3" 2398 | }, 2399 | "type": "library", 2400 | "extra": { 2401 | "branch-alias": { 2402 | "dev-master": "4.0-dev" 2403 | } 2404 | }, 2405 | "autoload": { 2406 | "classmap": [ 2407 | "src/" 2408 | ] 2409 | }, 2410 | "notification-url": "https://packagist.org/downloads/", 2411 | "license": [ 2412 | "BSD-3-Clause" 2413 | ], 2414 | "authors": [ 2415 | { 2416 | "name": "Sebastian Bergmann", 2417 | "email": "sebastian@phpunit.de" 2418 | }, 2419 | { 2420 | "name": "Jeff Welch", 2421 | "email": "whatthejeff@gmail.com" 2422 | }, 2423 | { 2424 | "name": "Adam Harvey", 2425 | "email": "aharvey@php.net" 2426 | } 2427 | ], 2428 | "description": "Provides functionality to recursively process PHP variables", 2429 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 2430 | "support": { 2431 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues", 2432 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" 2433 | }, 2434 | "funding": [ 2435 | { 2436 | "url": "https://github.com/sebastianbergmann", 2437 | "type": "github" 2438 | } 2439 | ], 2440 | "time": "2020-10-26T13:17:30+00:00" 2441 | }, 2442 | { 2443 | "name": "sebastian/resource-operations", 2444 | "version": "3.0.3", 2445 | "source": { 2446 | "type": "git", 2447 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 2448 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" 2449 | }, 2450 | "dist": { 2451 | "type": "zip", 2452 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", 2453 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", 2454 | "shasum": "" 2455 | }, 2456 | "require": { 2457 | "php": ">=7.3" 2458 | }, 2459 | "require-dev": { 2460 | "phpunit/phpunit": "^9.0" 2461 | }, 2462 | "type": "library", 2463 | "extra": { 2464 | "branch-alias": { 2465 | "dev-master": "3.0-dev" 2466 | } 2467 | }, 2468 | "autoload": { 2469 | "classmap": [ 2470 | "src/" 2471 | ] 2472 | }, 2473 | "notification-url": "https://packagist.org/downloads/", 2474 | "license": [ 2475 | "BSD-3-Clause" 2476 | ], 2477 | "authors": [ 2478 | { 2479 | "name": "Sebastian Bergmann", 2480 | "email": "sebastian@phpunit.de" 2481 | } 2482 | ], 2483 | "description": "Provides a list of PHP built-in functions that operate on resources", 2484 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 2485 | "support": { 2486 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues", 2487 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" 2488 | }, 2489 | "funding": [ 2490 | { 2491 | "url": "https://github.com/sebastianbergmann", 2492 | "type": "github" 2493 | } 2494 | ], 2495 | "time": "2020-09-28T06:45:17+00:00" 2496 | }, 2497 | { 2498 | "name": "sebastian/type", 2499 | "version": "2.3.1", 2500 | "source": { 2501 | "type": "git", 2502 | "url": "https://github.com/sebastianbergmann/type.git", 2503 | "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2" 2504 | }, 2505 | "dist": { 2506 | "type": "zip", 2507 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/81cd61ab7bbf2de744aba0ea61fae32f721df3d2", 2508 | "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2", 2509 | "shasum": "" 2510 | }, 2511 | "require": { 2512 | "php": ">=7.3" 2513 | }, 2514 | "require-dev": { 2515 | "phpunit/phpunit": "^9.3" 2516 | }, 2517 | "type": "library", 2518 | "extra": { 2519 | "branch-alias": { 2520 | "dev-master": "2.3-dev" 2521 | } 2522 | }, 2523 | "autoload": { 2524 | "classmap": [ 2525 | "src/" 2526 | ] 2527 | }, 2528 | "notification-url": "https://packagist.org/downloads/", 2529 | "license": [ 2530 | "BSD-3-Clause" 2531 | ], 2532 | "authors": [ 2533 | { 2534 | "name": "Sebastian Bergmann", 2535 | "email": "sebastian@phpunit.de", 2536 | "role": "lead" 2537 | } 2538 | ], 2539 | "description": "Collection of value objects that represent the types of the PHP type system", 2540 | "homepage": "https://github.com/sebastianbergmann/type", 2541 | "support": { 2542 | "issues": "https://github.com/sebastianbergmann/type/issues", 2543 | "source": "https://github.com/sebastianbergmann/type/tree/2.3.1" 2544 | }, 2545 | "funding": [ 2546 | { 2547 | "url": "https://github.com/sebastianbergmann", 2548 | "type": "github" 2549 | } 2550 | ], 2551 | "time": "2020-10-26T13:18:59+00:00" 2552 | }, 2553 | { 2554 | "name": "sebastian/version", 2555 | "version": "3.0.2", 2556 | "source": { 2557 | "type": "git", 2558 | "url": "https://github.com/sebastianbergmann/version.git", 2559 | "reference": "c6c1022351a901512170118436c764e473f6de8c" 2560 | }, 2561 | "dist": { 2562 | "type": "zip", 2563 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", 2564 | "reference": "c6c1022351a901512170118436c764e473f6de8c", 2565 | "shasum": "" 2566 | }, 2567 | "require": { 2568 | "php": ">=7.3" 2569 | }, 2570 | "type": "library", 2571 | "extra": { 2572 | "branch-alias": { 2573 | "dev-master": "3.0-dev" 2574 | } 2575 | }, 2576 | "autoload": { 2577 | "classmap": [ 2578 | "src/" 2579 | ] 2580 | }, 2581 | "notification-url": "https://packagist.org/downloads/", 2582 | "license": [ 2583 | "BSD-3-Clause" 2584 | ], 2585 | "authors": [ 2586 | { 2587 | "name": "Sebastian Bergmann", 2588 | "email": "sebastian@phpunit.de", 2589 | "role": "lead" 2590 | } 2591 | ], 2592 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 2593 | "homepage": "https://github.com/sebastianbergmann/version", 2594 | "support": { 2595 | "issues": "https://github.com/sebastianbergmann/version/issues", 2596 | "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" 2597 | }, 2598 | "funding": [ 2599 | { 2600 | "url": "https://github.com/sebastianbergmann", 2601 | "type": "github" 2602 | } 2603 | ], 2604 | "time": "2020-09-28T06:39:44+00:00" 2605 | }, 2606 | { 2607 | "name": "symfony/console", 2608 | "version": "v5.1.8", 2609 | "source": { 2610 | "type": "git", 2611 | "url": "https://github.com/symfony/console.git", 2612 | "reference": "e0b2c29c0fa6a69089209bbe8fcff4df2a313d0e" 2613 | }, 2614 | "dist": { 2615 | "type": "zip", 2616 | "url": "https://api.github.com/repos/symfony/console/zipball/e0b2c29c0fa6a69089209bbe8fcff4df2a313d0e", 2617 | "reference": "e0b2c29c0fa6a69089209bbe8fcff4df2a313d0e", 2618 | "shasum": "" 2619 | }, 2620 | "require": { 2621 | "php": ">=7.2.5", 2622 | "symfony/polyfill-mbstring": "~1.0", 2623 | "symfony/polyfill-php73": "^1.8", 2624 | "symfony/polyfill-php80": "^1.15", 2625 | "symfony/service-contracts": "^1.1|^2", 2626 | "symfony/string": "^5.1" 2627 | }, 2628 | "conflict": { 2629 | "symfony/dependency-injection": "<4.4", 2630 | "symfony/dotenv": "<5.1", 2631 | "symfony/event-dispatcher": "<4.4", 2632 | "symfony/lock": "<4.4", 2633 | "symfony/process": "<4.4" 2634 | }, 2635 | "provide": { 2636 | "psr/log-implementation": "1.0" 2637 | }, 2638 | "require-dev": { 2639 | "psr/log": "~1.0", 2640 | "symfony/config": "^4.4|^5.0", 2641 | "symfony/dependency-injection": "^4.4|^5.0", 2642 | "symfony/event-dispatcher": "^4.4|^5.0", 2643 | "symfony/lock": "^4.4|^5.0", 2644 | "symfony/process": "^4.4|^5.0", 2645 | "symfony/var-dumper": "^4.4|^5.0" 2646 | }, 2647 | "suggest": { 2648 | "psr/log": "For using the console logger", 2649 | "symfony/event-dispatcher": "", 2650 | "symfony/lock": "", 2651 | "symfony/process": "" 2652 | }, 2653 | "type": "library", 2654 | "autoload": { 2655 | "psr-4": { 2656 | "Symfony\\Component\\Console\\": "" 2657 | }, 2658 | "exclude-from-classmap": [ 2659 | "/Tests/" 2660 | ] 2661 | }, 2662 | "notification-url": "https://packagist.org/downloads/", 2663 | "license": [ 2664 | "MIT" 2665 | ], 2666 | "authors": [ 2667 | { 2668 | "name": "Fabien Potencier", 2669 | "email": "fabien@symfony.com" 2670 | }, 2671 | { 2672 | "name": "Symfony Community", 2673 | "homepage": "https://symfony.com/contributors" 2674 | } 2675 | ], 2676 | "description": "Symfony Console Component", 2677 | "homepage": "https://symfony.com", 2678 | "support": { 2679 | "source": "https://github.com/symfony/console/tree/v5.1.8" 2680 | }, 2681 | "funding": [ 2682 | { 2683 | "url": "https://symfony.com/sponsor", 2684 | "type": "custom" 2685 | }, 2686 | { 2687 | "url": "https://github.com/fabpot", 2688 | "type": "github" 2689 | }, 2690 | { 2691 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2692 | "type": "tidelift" 2693 | } 2694 | ], 2695 | "time": "2020-10-24T12:01:57+00:00" 2696 | }, 2697 | { 2698 | "name": "symfony/deprecation-contracts", 2699 | "version": "v2.2.0", 2700 | "source": { 2701 | "type": "git", 2702 | "url": "https://github.com/symfony/deprecation-contracts.git", 2703 | "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" 2704 | }, 2705 | "dist": { 2706 | "type": "zip", 2707 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", 2708 | "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", 2709 | "shasum": "" 2710 | }, 2711 | "require": { 2712 | "php": ">=7.1" 2713 | }, 2714 | "type": "library", 2715 | "extra": { 2716 | "branch-alias": { 2717 | "dev-master": "2.2-dev" 2718 | }, 2719 | "thanks": { 2720 | "name": "symfony/contracts", 2721 | "url": "https://github.com/symfony/contracts" 2722 | } 2723 | }, 2724 | "autoload": { 2725 | "files": [ 2726 | "function.php" 2727 | ] 2728 | }, 2729 | "notification-url": "https://packagist.org/downloads/", 2730 | "license": [ 2731 | "MIT" 2732 | ], 2733 | "authors": [ 2734 | { 2735 | "name": "Nicolas Grekas", 2736 | "email": "p@tchwork.com" 2737 | }, 2738 | { 2739 | "name": "Symfony Community", 2740 | "homepage": "https://symfony.com/contributors" 2741 | } 2742 | ], 2743 | "description": "A generic function and convention to trigger deprecation notices", 2744 | "homepage": "https://symfony.com", 2745 | "support": { 2746 | "source": "https://github.com/symfony/deprecation-contracts/tree/master" 2747 | }, 2748 | "funding": [ 2749 | { 2750 | "url": "https://symfony.com/sponsor", 2751 | "type": "custom" 2752 | }, 2753 | { 2754 | "url": "https://github.com/fabpot", 2755 | "type": "github" 2756 | }, 2757 | { 2758 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2759 | "type": "tidelift" 2760 | } 2761 | ], 2762 | "time": "2020-09-07T11:33:47+00:00" 2763 | }, 2764 | { 2765 | "name": "symfony/event-dispatcher", 2766 | "version": "v5.1.8", 2767 | "source": { 2768 | "type": "git", 2769 | "url": "https://github.com/symfony/event-dispatcher.git", 2770 | "reference": "26f4edae48c913fc183a3da0553fe63bdfbd361a" 2771 | }, 2772 | "dist": { 2773 | "type": "zip", 2774 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/26f4edae48c913fc183a3da0553fe63bdfbd361a", 2775 | "reference": "26f4edae48c913fc183a3da0553fe63bdfbd361a", 2776 | "shasum": "" 2777 | }, 2778 | "require": { 2779 | "php": ">=7.2.5", 2780 | "symfony/deprecation-contracts": "^2.1", 2781 | "symfony/event-dispatcher-contracts": "^2", 2782 | "symfony/polyfill-php80": "^1.15" 2783 | }, 2784 | "conflict": { 2785 | "symfony/dependency-injection": "<4.4" 2786 | }, 2787 | "provide": { 2788 | "psr/event-dispatcher-implementation": "1.0", 2789 | "symfony/event-dispatcher-implementation": "2.0" 2790 | }, 2791 | "require-dev": { 2792 | "psr/log": "~1.0", 2793 | "symfony/config": "^4.4|^5.0", 2794 | "symfony/dependency-injection": "^4.4|^5.0", 2795 | "symfony/error-handler": "^4.4|^5.0", 2796 | "symfony/expression-language": "^4.4|^5.0", 2797 | "symfony/http-foundation": "^4.4|^5.0", 2798 | "symfony/service-contracts": "^1.1|^2", 2799 | "symfony/stopwatch": "^4.4|^5.0" 2800 | }, 2801 | "suggest": { 2802 | "symfony/dependency-injection": "", 2803 | "symfony/http-kernel": "" 2804 | }, 2805 | "type": "library", 2806 | "autoload": { 2807 | "psr-4": { 2808 | "Symfony\\Component\\EventDispatcher\\": "" 2809 | }, 2810 | "exclude-from-classmap": [ 2811 | "/Tests/" 2812 | ] 2813 | }, 2814 | "notification-url": "https://packagist.org/downloads/", 2815 | "license": [ 2816 | "MIT" 2817 | ], 2818 | "authors": [ 2819 | { 2820 | "name": "Fabien Potencier", 2821 | "email": "fabien@symfony.com" 2822 | }, 2823 | { 2824 | "name": "Symfony Community", 2825 | "homepage": "https://symfony.com/contributors" 2826 | } 2827 | ], 2828 | "description": "Symfony EventDispatcher Component", 2829 | "homepage": "https://symfony.com", 2830 | "support": { 2831 | "source": "https://github.com/symfony/event-dispatcher/tree/v5.1.8" 2832 | }, 2833 | "funding": [ 2834 | { 2835 | "url": "https://symfony.com/sponsor", 2836 | "type": "custom" 2837 | }, 2838 | { 2839 | "url": "https://github.com/fabpot", 2840 | "type": "github" 2841 | }, 2842 | { 2843 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2844 | "type": "tidelift" 2845 | } 2846 | ], 2847 | "time": "2020-10-24T12:01:57+00:00" 2848 | }, 2849 | { 2850 | "name": "symfony/event-dispatcher-contracts", 2851 | "version": "v2.2.0", 2852 | "source": { 2853 | "type": "git", 2854 | "url": "https://github.com/symfony/event-dispatcher-contracts.git", 2855 | "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2" 2856 | }, 2857 | "dist": { 2858 | "type": "zip", 2859 | "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ba7d54483095a198fa51781bc608d17e84dffa2", 2860 | "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2", 2861 | "shasum": "" 2862 | }, 2863 | "require": { 2864 | "php": ">=7.2.5", 2865 | "psr/event-dispatcher": "^1" 2866 | }, 2867 | "suggest": { 2868 | "symfony/event-dispatcher-implementation": "" 2869 | }, 2870 | "type": "library", 2871 | "extra": { 2872 | "branch-alias": { 2873 | "dev-master": "2.2-dev" 2874 | }, 2875 | "thanks": { 2876 | "name": "symfony/contracts", 2877 | "url": "https://github.com/symfony/contracts" 2878 | } 2879 | }, 2880 | "autoload": { 2881 | "psr-4": { 2882 | "Symfony\\Contracts\\EventDispatcher\\": "" 2883 | } 2884 | }, 2885 | "notification-url": "https://packagist.org/downloads/", 2886 | "license": [ 2887 | "MIT" 2888 | ], 2889 | "authors": [ 2890 | { 2891 | "name": "Nicolas Grekas", 2892 | "email": "p@tchwork.com" 2893 | }, 2894 | { 2895 | "name": "Symfony Community", 2896 | "homepage": "https://symfony.com/contributors" 2897 | } 2898 | ], 2899 | "description": "Generic abstractions related to dispatching event", 2900 | "homepage": "https://symfony.com", 2901 | "keywords": [ 2902 | "abstractions", 2903 | "contracts", 2904 | "decoupling", 2905 | "interfaces", 2906 | "interoperability", 2907 | "standards" 2908 | ], 2909 | "support": { 2910 | "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.2.0" 2911 | }, 2912 | "funding": [ 2913 | { 2914 | "url": "https://symfony.com/sponsor", 2915 | "type": "custom" 2916 | }, 2917 | { 2918 | "url": "https://github.com/fabpot", 2919 | "type": "github" 2920 | }, 2921 | { 2922 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2923 | "type": "tidelift" 2924 | } 2925 | ], 2926 | "time": "2020-09-07T11:33:47+00:00" 2927 | }, 2928 | { 2929 | "name": "symfony/filesystem", 2930 | "version": "v5.1.8", 2931 | "source": { 2932 | "type": "git", 2933 | "url": "https://github.com/symfony/filesystem.git", 2934 | "reference": "df08650ea7aee2d925380069c131a66124d79177" 2935 | }, 2936 | "dist": { 2937 | "type": "zip", 2938 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/df08650ea7aee2d925380069c131a66124d79177", 2939 | "reference": "df08650ea7aee2d925380069c131a66124d79177", 2940 | "shasum": "" 2941 | }, 2942 | "require": { 2943 | "php": ">=7.2.5", 2944 | "symfony/polyfill-ctype": "~1.8" 2945 | }, 2946 | "type": "library", 2947 | "autoload": { 2948 | "psr-4": { 2949 | "Symfony\\Component\\Filesystem\\": "" 2950 | }, 2951 | "exclude-from-classmap": [ 2952 | "/Tests/" 2953 | ] 2954 | }, 2955 | "notification-url": "https://packagist.org/downloads/", 2956 | "license": [ 2957 | "MIT" 2958 | ], 2959 | "authors": [ 2960 | { 2961 | "name": "Fabien Potencier", 2962 | "email": "fabien@symfony.com" 2963 | }, 2964 | { 2965 | "name": "Symfony Community", 2966 | "homepage": "https://symfony.com/contributors" 2967 | } 2968 | ], 2969 | "description": "Symfony Filesystem Component", 2970 | "homepage": "https://symfony.com", 2971 | "support": { 2972 | "source": "https://github.com/symfony/filesystem/tree/v5.1.8" 2973 | }, 2974 | "funding": [ 2975 | { 2976 | "url": "https://symfony.com/sponsor", 2977 | "type": "custom" 2978 | }, 2979 | { 2980 | "url": "https://github.com/fabpot", 2981 | "type": "github" 2982 | }, 2983 | { 2984 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2985 | "type": "tidelift" 2986 | } 2987 | ], 2988 | "time": "2020-10-24T12:01:57+00:00" 2989 | }, 2990 | { 2991 | "name": "symfony/finder", 2992 | "version": "v5.1.8", 2993 | "source": { 2994 | "type": "git", 2995 | "url": "https://github.com/symfony/finder.git", 2996 | "reference": "e70eb5a69c2ff61ea135a13d2266e8914a67b3a0" 2997 | }, 2998 | "dist": { 2999 | "type": "zip", 3000 | "url": "https://api.github.com/repos/symfony/finder/zipball/e70eb5a69c2ff61ea135a13d2266e8914a67b3a0", 3001 | "reference": "e70eb5a69c2ff61ea135a13d2266e8914a67b3a0", 3002 | "shasum": "" 3003 | }, 3004 | "require": { 3005 | "php": ">=7.2.5" 3006 | }, 3007 | "type": "library", 3008 | "autoload": { 3009 | "psr-4": { 3010 | "Symfony\\Component\\Finder\\": "" 3011 | }, 3012 | "exclude-from-classmap": [ 3013 | "/Tests/" 3014 | ] 3015 | }, 3016 | "notification-url": "https://packagist.org/downloads/", 3017 | "license": [ 3018 | "MIT" 3019 | ], 3020 | "authors": [ 3021 | { 3022 | "name": "Fabien Potencier", 3023 | "email": "fabien@symfony.com" 3024 | }, 3025 | { 3026 | "name": "Symfony Community", 3027 | "homepage": "https://symfony.com/contributors" 3028 | } 3029 | ], 3030 | "description": "Symfony Finder Component", 3031 | "homepage": "https://symfony.com", 3032 | "support": { 3033 | "source": "https://github.com/symfony/finder/tree/v5.1.8" 3034 | }, 3035 | "funding": [ 3036 | { 3037 | "url": "https://symfony.com/sponsor", 3038 | "type": "custom" 3039 | }, 3040 | { 3041 | "url": "https://github.com/fabpot", 3042 | "type": "github" 3043 | }, 3044 | { 3045 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3046 | "type": "tidelift" 3047 | } 3048 | ], 3049 | "time": "2020-10-24T12:01:57+00:00" 3050 | }, 3051 | { 3052 | "name": "symfony/options-resolver", 3053 | "version": "v5.1.8", 3054 | "source": { 3055 | "type": "git", 3056 | "url": "https://github.com/symfony/options-resolver.git", 3057 | "reference": "c6a02905e4ffc7a1498e8ee019db2b477cd1cc02" 3058 | }, 3059 | "dist": { 3060 | "type": "zip", 3061 | "url": "https://api.github.com/repos/symfony/options-resolver/zipball/c6a02905e4ffc7a1498e8ee019db2b477cd1cc02", 3062 | "reference": "c6a02905e4ffc7a1498e8ee019db2b477cd1cc02", 3063 | "shasum": "" 3064 | }, 3065 | "require": { 3066 | "php": ">=7.2.5", 3067 | "symfony/deprecation-contracts": "^2.1", 3068 | "symfony/polyfill-php80": "^1.15" 3069 | }, 3070 | "type": "library", 3071 | "autoload": { 3072 | "psr-4": { 3073 | "Symfony\\Component\\OptionsResolver\\": "" 3074 | }, 3075 | "exclude-from-classmap": [ 3076 | "/Tests/" 3077 | ] 3078 | }, 3079 | "notification-url": "https://packagist.org/downloads/", 3080 | "license": [ 3081 | "MIT" 3082 | ], 3083 | "authors": [ 3084 | { 3085 | "name": "Fabien Potencier", 3086 | "email": "fabien@symfony.com" 3087 | }, 3088 | { 3089 | "name": "Symfony Community", 3090 | "homepage": "https://symfony.com/contributors" 3091 | } 3092 | ], 3093 | "description": "Symfony OptionsResolver Component", 3094 | "homepage": "https://symfony.com", 3095 | "keywords": [ 3096 | "config", 3097 | "configuration", 3098 | "options" 3099 | ], 3100 | "support": { 3101 | "source": "https://github.com/symfony/options-resolver/tree/v5.1.8" 3102 | }, 3103 | "funding": [ 3104 | { 3105 | "url": "https://symfony.com/sponsor", 3106 | "type": "custom" 3107 | }, 3108 | { 3109 | "url": "https://github.com/fabpot", 3110 | "type": "github" 3111 | }, 3112 | { 3113 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3114 | "type": "tidelift" 3115 | } 3116 | ], 3117 | "time": "2020-10-24T12:01:57+00:00" 3118 | }, 3119 | { 3120 | "name": "symfony/polyfill-ctype", 3121 | "version": "v1.20.0", 3122 | "source": { 3123 | "type": "git", 3124 | "url": "https://github.com/symfony/polyfill-ctype.git", 3125 | "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" 3126 | }, 3127 | "dist": { 3128 | "type": "zip", 3129 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", 3130 | "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", 3131 | "shasum": "" 3132 | }, 3133 | "require": { 3134 | "php": ">=7.1" 3135 | }, 3136 | "suggest": { 3137 | "ext-ctype": "For best performance" 3138 | }, 3139 | "type": "library", 3140 | "extra": { 3141 | "branch-alias": { 3142 | "dev-main": "1.20-dev" 3143 | }, 3144 | "thanks": { 3145 | "name": "symfony/polyfill", 3146 | "url": "https://github.com/symfony/polyfill" 3147 | } 3148 | }, 3149 | "autoload": { 3150 | "psr-4": { 3151 | "Symfony\\Polyfill\\Ctype\\": "" 3152 | }, 3153 | "files": [ 3154 | "bootstrap.php" 3155 | ] 3156 | }, 3157 | "notification-url": "https://packagist.org/downloads/", 3158 | "license": [ 3159 | "MIT" 3160 | ], 3161 | "authors": [ 3162 | { 3163 | "name": "Gert de Pagter", 3164 | "email": "BackEndTea@gmail.com" 3165 | }, 3166 | { 3167 | "name": "Symfony Community", 3168 | "homepage": "https://symfony.com/contributors" 3169 | } 3170 | ], 3171 | "description": "Symfony polyfill for ctype functions", 3172 | "homepage": "https://symfony.com", 3173 | "keywords": [ 3174 | "compatibility", 3175 | "ctype", 3176 | "polyfill", 3177 | "portable" 3178 | ], 3179 | "support": { 3180 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" 3181 | }, 3182 | "funding": [ 3183 | { 3184 | "url": "https://symfony.com/sponsor", 3185 | "type": "custom" 3186 | }, 3187 | { 3188 | "url": "https://github.com/fabpot", 3189 | "type": "github" 3190 | }, 3191 | { 3192 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3193 | "type": "tidelift" 3194 | } 3195 | ], 3196 | "time": "2020-10-23T14:02:19+00:00" 3197 | }, 3198 | { 3199 | "name": "symfony/polyfill-intl-grapheme", 3200 | "version": "v1.20.0", 3201 | "source": { 3202 | "type": "git", 3203 | "url": "https://github.com/symfony/polyfill-intl-grapheme.git", 3204 | "reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c" 3205 | }, 3206 | "dist": { 3207 | "type": "zip", 3208 | "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c", 3209 | "reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c", 3210 | "shasum": "" 3211 | }, 3212 | "require": { 3213 | "php": ">=7.1" 3214 | }, 3215 | "suggest": { 3216 | "ext-intl": "For best performance" 3217 | }, 3218 | "type": "library", 3219 | "extra": { 3220 | "branch-alias": { 3221 | "dev-main": "1.20-dev" 3222 | }, 3223 | "thanks": { 3224 | "name": "symfony/polyfill", 3225 | "url": "https://github.com/symfony/polyfill" 3226 | } 3227 | }, 3228 | "autoload": { 3229 | "psr-4": { 3230 | "Symfony\\Polyfill\\Intl\\Grapheme\\": "" 3231 | }, 3232 | "files": [ 3233 | "bootstrap.php" 3234 | ] 3235 | }, 3236 | "notification-url": "https://packagist.org/downloads/", 3237 | "license": [ 3238 | "MIT" 3239 | ], 3240 | "authors": [ 3241 | { 3242 | "name": "Nicolas Grekas", 3243 | "email": "p@tchwork.com" 3244 | }, 3245 | { 3246 | "name": "Symfony Community", 3247 | "homepage": "https://symfony.com/contributors" 3248 | } 3249 | ], 3250 | "description": "Symfony polyfill for intl's grapheme_* functions", 3251 | "homepage": "https://symfony.com", 3252 | "keywords": [ 3253 | "compatibility", 3254 | "grapheme", 3255 | "intl", 3256 | "polyfill", 3257 | "portable", 3258 | "shim" 3259 | ], 3260 | "support": { 3261 | "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.20.0" 3262 | }, 3263 | "funding": [ 3264 | { 3265 | "url": "https://symfony.com/sponsor", 3266 | "type": "custom" 3267 | }, 3268 | { 3269 | "url": "https://github.com/fabpot", 3270 | "type": "github" 3271 | }, 3272 | { 3273 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3274 | "type": "tidelift" 3275 | } 3276 | ], 3277 | "time": "2020-10-23T14:02:19+00:00" 3278 | }, 3279 | { 3280 | "name": "symfony/polyfill-intl-normalizer", 3281 | "version": "v1.20.0", 3282 | "source": { 3283 | "type": "git", 3284 | "url": "https://github.com/symfony/polyfill-intl-normalizer.git", 3285 | "reference": "727d1096295d807c309fb01a851577302394c897" 3286 | }, 3287 | "dist": { 3288 | "type": "zip", 3289 | "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897", 3290 | "reference": "727d1096295d807c309fb01a851577302394c897", 3291 | "shasum": "" 3292 | }, 3293 | "require": { 3294 | "php": ">=7.1" 3295 | }, 3296 | "suggest": { 3297 | "ext-intl": "For best performance" 3298 | }, 3299 | "type": "library", 3300 | "extra": { 3301 | "branch-alias": { 3302 | "dev-main": "1.20-dev" 3303 | }, 3304 | "thanks": { 3305 | "name": "symfony/polyfill", 3306 | "url": "https://github.com/symfony/polyfill" 3307 | } 3308 | }, 3309 | "autoload": { 3310 | "psr-4": { 3311 | "Symfony\\Polyfill\\Intl\\Normalizer\\": "" 3312 | }, 3313 | "files": [ 3314 | "bootstrap.php" 3315 | ], 3316 | "classmap": [ 3317 | "Resources/stubs" 3318 | ] 3319 | }, 3320 | "notification-url": "https://packagist.org/downloads/", 3321 | "license": [ 3322 | "MIT" 3323 | ], 3324 | "authors": [ 3325 | { 3326 | "name": "Nicolas Grekas", 3327 | "email": "p@tchwork.com" 3328 | }, 3329 | { 3330 | "name": "Symfony Community", 3331 | "homepage": "https://symfony.com/contributors" 3332 | } 3333 | ], 3334 | "description": "Symfony polyfill for intl's Normalizer class and related functions", 3335 | "homepage": "https://symfony.com", 3336 | "keywords": [ 3337 | "compatibility", 3338 | "intl", 3339 | "normalizer", 3340 | "polyfill", 3341 | "portable", 3342 | "shim" 3343 | ], 3344 | "support": { 3345 | "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.20.0" 3346 | }, 3347 | "funding": [ 3348 | { 3349 | "url": "https://symfony.com/sponsor", 3350 | "type": "custom" 3351 | }, 3352 | { 3353 | "url": "https://github.com/fabpot", 3354 | "type": "github" 3355 | }, 3356 | { 3357 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3358 | "type": "tidelift" 3359 | } 3360 | ], 3361 | "time": "2020-10-23T14:02:19+00:00" 3362 | }, 3363 | { 3364 | "name": "symfony/polyfill-mbstring", 3365 | "version": "v1.20.0", 3366 | "source": { 3367 | "type": "git", 3368 | "url": "https://github.com/symfony/polyfill-mbstring.git", 3369 | "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" 3370 | }, 3371 | "dist": { 3372 | "type": "zip", 3373 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", 3374 | "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", 3375 | "shasum": "" 3376 | }, 3377 | "require": { 3378 | "php": ">=7.1" 3379 | }, 3380 | "suggest": { 3381 | "ext-mbstring": "For best performance" 3382 | }, 3383 | "type": "library", 3384 | "extra": { 3385 | "branch-alias": { 3386 | "dev-main": "1.20-dev" 3387 | }, 3388 | "thanks": { 3389 | "name": "symfony/polyfill", 3390 | "url": "https://github.com/symfony/polyfill" 3391 | } 3392 | }, 3393 | "autoload": { 3394 | "psr-4": { 3395 | "Symfony\\Polyfill\\Mbstring\\": "" 3396 | }, 3397 | "files": [ 3398 | "bootstrap.php" 3399 | ] 3400 | }, 3401 | "notification-url": "https://packagist.org/downloads/", 3402 | "license": [ 3403 | "MIT" 3404 | ], 3405 | "authors": [ 3406 | { 3407 | "name": "Nicolas Grekas", 3408 | "email": "p@tchwork.com" 3409 | }, 3410 | { 3411 | "name": "Symfony Community", 3412 | "homepage": "https://symfony.com/contributors" 3413 | } 3414 | ], 3415 | "description": "Symfony polyfill for the Mbstring extension", 3416 | "homepage": "https://symfony.com", 3417 | "keywords": [ 3418 | "compatibility", 3419 | "mbstring", 3420 | "polyfill", 3421 | "portable", 3422 | "shim" 3423 | ], 3424 | "support": { 3425 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0" 3426 | }, 3427 | "funding": [ 3428 | { 3429 | "url": "https://symfony.com/sponsor", 3430 | "type": "custom" 3431 | }, 3432 | { 3433 | "url": "https://github.com/fabpot", 3434 | "type": "github" 3435 | }, 3436 | { 3437 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3438 | "type": "tidelift" 3439 | } 3440 | ], 3441 | "time": "2020-10-23T14:02:19+00:00" 3442 | }, 3443 | { 3444 | "name": "symfony/polyfill-php70", 3445 | "version": "v1.20.0", 3446 | "source": { 3447 | "type": "git", 3448 | "url": "https://github.com/symfony/polyfill-php70.git", 3449 | "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" 3450 | }, 3451 | "dist": { 3452 | "type": "zip", 3453 | "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", 3454 | "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", 3455 | "shasum": "" 3456 | }, 3457 | "require": { 3458 | "php": ">=7.1" 3459 | }, 3460 | "type": "metapackage", 3461 | "extra": { 3462 | "branch-alias": { 3463 | "dev-main": "1.20-dev" 3464 | }, 3465 | "thanks": { 3466 | "name": "symfony/polyfill", 3467 | "url": "https://github.com/symfony/polyfill" 3468 | } 3469 | }, 3470 | "notification-url": "https://packagist.org/downloads/", 3471 | "license": [ 3472 | "MIT" 3473 | ], 3474 | "authors": [ 3475 | { 3476 | "name": "Nicolas Grekas", 3477 | "email": "p@tchwork.com" 3478 | }, 3479 | { 3480 | "name": "Symfony Community", 3481 | "homepage": "https://symfony.com/contributors" 3482 | } 3483 | ], 3484 | "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", 3485 | "homepage": "https://symfony.com", 3486 | "keywords": [ 3487 | "compatibility", 3488 | "polyfill", 3489 | "portable", 3490 | "shim" 3491 | ], 3492 | "support": { 3493 | "source": "https://github.com/symfony/polyfill-php70/tree/v1.20.0" 3494 | }, 3495 | "funding": [ 3496 | { 3497 | "url": "https://symfony.com/sponsor", 3498 | "type": "custom" 3499 | }, 3500 | { 3501 | "url": "https://github.com/fabpot", 3502 | "type": "github" 3503 | }, 3504 | { 3505 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3506 | "type": "tidelift" 3507 | } 3508 | ], 3509 | "time": "2020-10-23T14:02:19+00:00" 3510 | }, 3511 | { 3512 | "name": "symfony/polyfill-php72", 3513 | "version": "v1.20.0", 3514 | "source": { 3515 | "type": "git", 3516 | "url": "https://github.com/symfony/polyfill-php72.git", 3517 | "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930" 3518 | }, 3519 | "dist": { 3520 | "type": "zip", 3521 | "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cede45fcdfabdd6043b3592e83678e42ec69e930", 3522 | "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930", 3523 | "shasum": "" 3524 | }, 3525 | "require": { 3526 | "php": ">=7.1" 3527 | }, 3528 | "type": "library", 3529 | "extra": { 3530 | "branch-alias": { 3531 | "dev-main": "1.20-dev" 3532 | }, 3533 | "thanks": { 3534 | "name": "symfony/polyfill", 3535 | "url": "https://github.com/symfony/polyfill" 3536 | } 3537 | }, 3538 | "autoload": { 3539 | "psr-4": { 3540 | "Symfony\\Polyfill\\Php72\\": "" 3541 | }, 3542 | "files": [ 3543 | "bootstrap.php" 3544 | ] 3545 | }, 3546 | "notification-url": "https://packagist.org/downloads/", 3547 | "license": [ 3548 | "MIT" 3549 | ], 3550 | "authors": [ 3551 | { 3552 | "name": "Nicolas Grekas", 3553 | "email": "p@tchwork.com" 3554 | }, 3555 | { 3556 | "name": "Symfony Community", 3557 | "homepage": "https://symfony.com/contributors" 3558 | } 3559 | ], 3560 | "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", 3561 | "homepage": "https://symfony.com", 3562 | "keywords": [ 3563 | "compatibility", 3564 | "polyfill", 3565 | "portable", 3566 | "shim" 3567 | ], 3568 | "support": { 3569 | "source": "https://github.com/symfony/polyfill-php72/tree/v1.20.0" 3570 | }, 3571 | "funding": [ 3572 | { 3573 | "url": "https://symfony.com/sponsor", 3574 | "type": "custom" 3575 | }, 3576 | { 3577 | "url": "https://github.com/fabpot", 3578 | "type": "github" 3579 | }, 3580 | { 3581 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3582 | "type": "tidelift" 3583 | } 3584 | ], 3585 | "time": "2020-10-23T14:02:19+00:00" 3586 | }, 3587 | { 3588 | "name": "symfony/polyfill-php73", 3589 | "version": "v1.20.0", 3590 | "source": { 3591 | "type": "git", 3592 | "url": "https://github.com/symfony/polyfill-php73.git", 3593 | "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed" 3594 | }, 3595 | "dist": { 3596 | "type": "zip", 3597 | "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed", 3598 | "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed", 3599 | "shasum": "" 3600 | }, 3601 | "require": { 3602 | "php": ">=7.1" 3603 | }, 3604 | "type": "library", 3605 | "extra": { 3606 | "branch-alias": { 3607 | "dev-main": "1.20-dev" 3608 | }, 3609 | "thanks": { 3610 | "name": "symfony/polyfill", 3611 | "url": "https://github.com/symfony/polyfill" 3612 | } 3613 | }, 3614 | "autoload": { 3615 | "psr-4": { 3616 | "Symfony\\Polyfill\\Php73\\": "" 3617 | }, 3618 | "files": [ 3619 | "bootstrap.php" 3620 | ], 3621 | "classmap": [ 3622 | "Resources/stubs" 3623 | ] 3624 | }, 3625 | "notification-url": "https://packagist.org/downloads/", 3626 | "license": [ 3627 | "MIT" 3628 | ], 3629 | "authors": [ 3630 | { 3631 | "name": "Nicolas Grekas", 3632 | "email": "p@tchwork.com" 3633 | }, 3634 | { 3635 | "name": "Symfony Community", 3636 | "homepage": "https://symfony.com/contributors" 3637 | } 3638 | ], 3639 | "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", 3640 | "homepage": "https://symfony.com", 3641 | "keywords": [ 3642 | "compatibility", 3643 | "polyfill", 3644 | "portable", 3645 | "shim" 3646 | ], 3647 | "support": { 3648 | "source": "https://github.com/symfony/polyfill-php73/tree/v1.20.0" 3649 | }, 3650 | "funding": [ 3651 | { 3652 | "url": "https://symfony.com/sponsor", 3653 | "type": "custom" 3654 | }, 3655 | { 3656 | "url": "https://github.com/fabpot", 3657 | "type": "github" 3658 | }, 3659 | { 3660 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3661 | "type": "tidelift" 3662 | } 3663 | ], 3664 | "time": "2020-10-23T14:02:19+00:00" 3665 | }, 3666 | { 3667 | "name": "symfony/polyfill-php80", 3668 | "version": "v1.20.0", 3669 | "source": { 3670 | "type": "git", 3671 | "url": "https://github.com/symfony/polyfill-php80.git", 3672 | "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" 3673 | }, 3674 | "dist": { 3675 | "type": "zip", 3676 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", 3677 | "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", 3678 | "shasum": "" 3679 | }, 3680 | "require": { 3681 | "php": ">=7.1" 3682 | }, 3683 | "type": "library", 3684 | "extra": { 3685 | "branch-alias": { 3686 | "dev-main": "1.20-dev" 3687 | }, 3688 | "thanks": { 3689 | "name": "symfony/polyfill", 3690 | "url": "https://github.com/symfony/polyfill" 3691 | } 3692 | }, 3693 | "autoload": { 3694 | "psr-4": { 3695 | "Symfony\\Polyfill\\Php80\\": "" 3696 | }, 3697 | "files": [ 3698 | "bootstrap.php" 3699 | ], 3700 | "classmap": [ 3701 | "Resources/stubs" 3702 | ] 3703 | }, 3704 | "notification-url": "https://packagist.org/downloads/", 3705 | "license": [ 3706 | "MIT" 3707 | ], 3708 | "authors": [ 3709 | { 3710 | "name": "Ion Bazan", 3711 | "email": "ion.bazan@gmail.com" 3712 | }, 3713 | { 3714 | "name": "Nicolas Grekas", 3715 | "email": "p@tchwork.com" 3716 | }, 3717 | { 3718 | "name": "Symfony Community", 3719 | "homepage": "https://symfony.com/contributors" 3720 | } 3721 | ], 3722 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 3723 | "homepage": "https://symfony.com", 3724 | "keywords": [ 3725 | "compatibility", 3726 | "polyfill", 3727 | "portable", 3728 | "shim" 3729 | ], 3730 | "support": { 3731 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.20.0" 3732 | }, 3733 | "funding": [ 3734 | { 3735 | "url": "https://symfony.com/sponsor", 3736 | "type": "custom" 3737 | }, 3738 | { 3739 | "url": "https://github.com/fabpot", 3740 | "type": "github" 3741 | }, 3742 | { 3743 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3744 | "type": "tidelift" 3745 | } 3746 | ], 3747 | "time": "2020-10-23T14:02:19+00:00" 3748 | }, 3749 | { 3750 | "name": "symfony/process", 3751 | "version": "v5.1.8", 3752 | "source": { 3753 | "type": "git", 3754 | "url": "https://github.com/symfony/process.git", 3755 | "reference": "f00872c3f6804150d6a0f73b4151daab96248101" 3756 | }, 3757 | "dist": { 3758 | "type": "zip", 3759 | "url": "https://api.github.com/repos/symfony/process/zipball/f00872c3f6804150d6a0f73b4151daab96248101", 3760 | "reference": "f00872c3f6804150d6a0f73b4151daab96248101", 3761 | "shasum": "" 3762 | }, 3763 | "require": { 3764 | "php": ">=7.2.5", 3765 | "symfony/polyfill-php80": "^1.15" 3766 | }, 3767 | "type": "library", 3768 | "autoload": { 3769 | "psr-4": { 3770 | "Symfony\\Component\\Process\\": "" 3771 | }, 3772 | "exclude-from-classmap": [ 3773 | "/Tests/" 3774 | ] 3775 | }, 3776 | "notification-url": "https://packagist.org/downloads/", 3777 | "license": [ 3778 | "MIT" 3779 | ], 3780 | "authors": [ 3781 | { 3782 | "name": "Fabien Potencier", 3783 | "email": "fabien@symfony.com" 3784 | }, 3785 | { 3786 | "name": "Symfony Community", 3787 | "homepage": "https://symfony.com/contributors" 3788 | } 3789 | ], 3790 | "description": "Symfony Process Component", 3791 | "homepage": "https://symfony.com", 3792 | "support": { 3793 | "source": "https://github.com/symfony/process/tree/v5.1.8" 3794 | }, 3795 | "funding": [ 3796 | { 3797 | "url": "https://symfony.com/sponsor", 3798 | "type": "custom" 3799 | }, 3800 | { 3801 | "url": "https://github.com/fabpot", 3802 | "type": "github" 3803 | }, 3804 | { 3805 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3806 | "type": "tidelift" 3807 | } 3808 | ], 3809 | "time": "2020-10-24T12:01:57+00:00" 3810 | }, 3811 | { 3812 | "name": "symfony/service-contracts", 3813 | "version": "v2.2.0", 3814 | "source": { 3815 | "type": "git", 3816 | "url": "https://github.com/symfony/service-contracts.git", 3817 | "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" 3818 | }, 3819 | "dist": { 3820 | "type": "zip", 3821 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", 3822 | "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", 3823 | "shasum": "" 3824 | }, 3825 | "require": { 3826 | "php": ">=7.2.5", 3827 | "psr/container": "^1.0" 3828 | }, 3829 | "suggest": { 3830 | "symfony/service-implementation": "" 3831 | }, 3832 | "type": "library", 3833 | "extra": { 3834 | "branch-alias": { 3835 | "dev-master": "2.2-dev" 3836 | }, 3837 | "thanks": { 3838 | "name": "symfony/contracts", 3839 | "url": "https://github.com/symfony/contracts" 3840 | } 3841 | }, 3842 | "autoload": { 3843 | "psr-4": { 3844 | "Symfony\\Contracts\\Service\\": "" 3845 | } 3846 | }, 3847 | "notification-url": "https://packagist.org/downloads/", 3848 | "license": [ 3849 | "MIT" 3850 | ], 3851 | "authors": [ 3852 | { 3853 | "name": "Nicolas Grekas", 3854 | "email": "p@tchwork.com" 3855 | }, 3856 | { 3857 | "name": "Symfony Community", 3858 | "homepage": "https://symfony.com/contributors" 3859 | } 3860 | ], 3861 | "description": "Generic abstractions related to writing services", 3862 | "homepage": "https://symfony.com", 3863 | "keywords": [ 3864 | "abstractions", 3865 | "contracts", 3866 | "decoupling", 3867 | "interfaces", 3868 | "interoperability", 3869 | "standards" 3870 | ], 3871 | "support": { 3872 | "source": "https://github.com/symfony/service-contracts/tree/master" 3873 | }, 3874 | "funding": [ 3875 | { 3876 | "url": "https://symfony.com/sponsor", 3877 | "type": "custom" 3878 | }, 3879 | { 3880 | "url": "https://github.com/fabpot", 3881 | "type": "github" 3882 | }, 3883 | { 3884 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3885 | "type": "tidelift" 3886 | } 3887 | ], 3888 | "time": "2020-09-07T11:33:47+00:00" 3889 | }, 3890 | { 3891 | "name": "symfony/stopwatch", 3892 | "version": "v5.1.8", 3893 | "source": { 3894 | "type": "git", 3895 | "url": "https://github.com/symfony/stopwatch.git", 3896 | "reference": "3d9f57c89011f0266e6b1d469e5c0110513859d5" 3897 | }, 3898 | "dist": { 3899 | "type": "zip", 3900 | "url": "https://api.github.com/repos/symfony/stopwatch/zipball/3d9f57c89011f0266e6b1d469e5c0110513859d5", 3901 | "reference": "3d9f57c89011f0266e6b1d469e5c0110513859d5", 3902 | "shasum": "" 3903 | }, 3904 | "require": { 3905 | "php": ">=7.2.5", 3906 | "symfony/service-contracts": "^1.0|^2" 3907 | }, 3908 | "type": "library", 3909 | "autoload": { 3910 | "psr-4": { 3911 | "Symfony\\Component\\Stopwatch\\": "" 3912 | }, 3913 | "exclude-from-classmap": [ 3914 | "/Tests/" 3915 | ] 3916 | }, 3917 | "notification-url": "https://packagist.org/downloads/", 3918 | "license": [ 3919 | "MIT" 3920 | ], 3921 | "authors": [ 3922 | { 3923 | "name": "Fabien Potencier", 3924 | "email": "fabien@symfony.com" 3925 | }, 3926 | { 3927 | "name": "Symfony Community", 3928 | "homepage": "https://symfony.com/contributors" 3929 | } 3930 | ], 3931 | "description": "Symfony Stopwatch Component", 3932 | "homepage": "https://symfony.com", 3933 | "support": { 3934 | "source": "https://github.com/symfony/stopwatch/tree/v5.1.8" 3935 | }, 3936 | "funding": [ 3937 | { 3938 | "url": "https://symfony.com/sponsor", 3939 | "type": "custom" 3940 | }, 3941 | { 3942 | "url": "https://github.com/fabpot", 3943 | "type": "github" 3944 | }, 3945 | { 3946 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3947 | "type": "tidelift" 3948 | } 3949 | ], 3950 | "time": "2020-10-24T12:01:57+00:00" 3951 | }, 3952 | { 3953 | "name": "symfony/string", 3954 | "version": "v5.1.8", 3955 | "source": { 3956 | "type": "git", 3957 | "url": "https://github.com/symfony/string.git", 3958 | "reference": "a97573e960303db71be0dd8fda9be3bca5e0feea" 3959 | }, 3960 | "dist": { 3961 | "type": "zip", 3962 | "url": "https://api.github.com/repos/symfony/string/zipball/a97573e960303db71be0dd8fda9be3bca5e0feea", 3963 | "reference": "a97573e960303db71be0dd8fda9be3bca5e0feea", 3964 | "shasum": "" 3965 | }, 3966 | "require": { 3967 | "php": ">=7.2.5", 3968 | "symfony/polyfill-ctype": "~1.8", 3969 | "symfony/polyfill-intl-grapheme": "~1.0", 3970 | "symfony/polyfill-intl-normalizer": "~1.0", 3971 | "symfony/polyfill-mbstring": "~1.0", 3972 | "symfony/polyfill-php80": "~1.15" 3973 | }, 3974 | "require-dev": { 3975 | "symfony/error-handler": "^4.4|^5.0", 3976 | "symfony/http-client": "^4.4|^5.0", 3977 | "symfony/translation-contracts": "^1.1|^2", 3978 | "symfony/var-exporter": "^4.4|^5.0" 3979 | }, 3980 | "type": "library", 3981 | "autoload": { 3982 | "psr-4": { 3983 | "Symfony\\Component\\String\\": "" 3984 | }, 3985 | "files": [ 3986 | "Resources/functions.php" 3987 | ], 3988 | "exclude-from-classmap": [ 3989 | "/Tests/" 3990 | ] 3991 | }, 3992 | "notification-url": "https://packagist.org/downloads/", 3993 | "license": [ 3994 | "MIT" 3995 | ], 3996 | "authors": [ 3997 | { 3998 | "name": "Nicolas Grekas", 3999 | "email": "p@tchwork.com" 4000 | }, 4001 | { 4002 | "name": "Symfony Community", 4003 | "homepage": "https://symfony.com/contributors" 4004 | } 4005 | ], 4006 | "description": "Symfony String component", 4007 | "homepage": "https://symfony.com", 4008 | "keywords": [ 4009 | "grapheme", 4010 | "i18n", 4011 | "string", 4012 | "unicode", 4013 | "utf-8", 4014 | "utf8" 4015 | ], 4016 | "support": { 4017 | "source": "https://github.com/symfony/string/tree/v5.1.8" 4018 | }, 4019 | "funding": [ 4020 | { 4021 | "url": "https://symfony.com/sponsor", 4022 | "type": "custom" 4023 | }, 4024 | { 4025 | "url": "https://github.com/fabpot", 4026 | "type": "github" 4027 | }, 4028 | { 4029 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 4030 | "type": "tidelift" 4031 | } 4032 | ], 4033 | "time": "2020-10-24T12:01:57+00:00" 4034 | }, 4035 | { 4036 | "name": "theseer/tokenizer", 4037 | "version": "1.2.0", 4038 | "source": { 4039 | "type": "git", 4040 | "url": "https://github.com/theseer/tokenizer.git", 4041 | "reference": "75a63c33a8577608444246075ea0af0d052e452a" 4042 | }, 4043 | "dist": { 4044 | "type": "zip", 4045 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", 4046 | "reference": "75a63c33a8577608444246075ea0af0d052e452a", 4047 | "shasum": "" 4048 | }, 4049 | "require": { 4050 | "ext-dom": "*", 4051 | "ext-tokenizer": "*", 4052 | "ext-xmlwriter": "*", 4053 | "php": "^7.2 || ^8.0" 4054 | }, 4055 | "type": "library", 4056 | "autoload": { 4057 | "classmap": [ 4058 | "src/" 4059 | ] 4060 | }, 4061 | "notification-url": "https://packagist.org/downloads/", 4062 | "license": [ 4063 | "BSD-3-Clause" 4064 | ], 4065 | "authors": [ 4066 | { 4067 | "name": "Arne Blankerts", 4068 | "email": "arne@blankerts.de", 4069 | "role": "Developer" 4070 | } 4071 | ], 4072 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 4073 | "support": { 4074 | "issues": "https://github.com/theseer/tokenizer/issues", 4075 | "source": "https://github.com/theseer/tokenizer/tree/master" 4076 | }, 4077 | "funding": [ 4078 | { 4079 | "url": "https://github.com/theseer", 4080 | "type": "github" 4081 | } 4082 | ], 4083 | "time": "2020-07-12T23:59:07+00:00" 4084 | }, 4085 | { 4086 | "name": "webmozart/assert", 4087 | "version": "1.9.1", 4088 | "source": { 4089 | "type": "git", 4090 | "url": "https://github.com/webmozart/assert.git", 4091 | "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" 4092 | }, 4093 | "dist": { 4094 | "type": "zip", 4095 | "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", 4096 | "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", 4097 | "shasum": "" 4098 | }, 4099 | "require": { 4100 | "php": "^5.3.3 || ^7.0 || ^8.0", 4101 | "symfony/polyfill-ctype": "^1.8" 4102 | }, 4103 | "conflict": { 4104 | "phpstan/phpstan": "<0.12.20", 4105 | "vimeo/psalm": "<3.9.1" 4106 | }, 4107 | "require-dev": { 4108 | "phpunit/phpunit": "^4.8.36 || ^7.5.13" 4109 | }, 4110 | "type": "library", 4111 | "autoload": { 4112 | "psr-4": { 4113 | "Webmozart\\Assert\\": "src/" 4114 | } 4115 | }, 4116 | "notification-url": "https://packagist.org/downloads/", 4117 | "license": [ 4118 | "MIT" 4119 | ], 4120 | "authors": [ 4121 | { 4122 | "name": "Bernhard Schussek", 4123 | "email": "bschussek@gmail.com" 4124 | } 4125 | ], 4126 | "description": "Assertions to validate method input/output with nice error messages.", 4127 | "keywords": [ 4128 | "assert", 4129 | "check", 4130 | "validate" 4131 | ], 4132 | "support": { 4133 | "issues": "https://github.com/webmozart/assert/issues", 4134 | "source": "https://github.com/webmozart/assert/tree/master" 4135 | }, 4136 | "time": "2020-07-08T17:02:28+00:00" 4137 | } 4138 | ], 4139 | "aliases": [], 4140 | "minimum-stability": "stable", 4141 | "stability-flags": [], 4142 | "prefer-stable": false, 4143 | "prefer-lowest": false, 4144 | "platform": { 4145 | "php": ">=7.2.0" 4146 | }, 4147 | "platform-dev": [], 4148 | "plugin-api-version": "2.0.0" 4149 | } 4150 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | src 6 | 7 | 8 | vendor 9 | 10 | 11 | 12 | 13 | tests 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Checks/AllInOneCheck.php: -------------------------------------------------------------------------------- 1 | setUp(true); 20 | $errors = []; 21 | 22 | foreach ($this->checks as $check) { 23 | $checkStatus = $check->getStatus(); 24 | if (!$checkStatus->isUp()) { 25 | $status->setUp(false); 26 | $errors[] = $checkStatus->getError(); 27 | } 28 | } 29 | 30 | if (!$status->isUp()) { 31 | $status->setError($errors); 32 | } 33 | 34 | return $status; 35 | } 36 | 37 | public function add(CheckInterface $check): self 38 | { 39 | $this->checks[] = $check; 40 | 41 | return $this; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Checks/CheckInterface.php: -------------------------------------------------------------------------------- 1 | url = $this->normilizeUrl($url); 25 | } 26 | 27 | public function setConnectionTimeout(int $connectionTimeout): self 28 | { 29 | $this->connectionTimeout = $connectionTimeout; 30 | 31 | return $this; 32 | } 33 | 34 | public function getStatus(): Status 35 | { 36 | $status = new Status(); 37 | 38 | try { 39 | $context = \stream_context_create(['http' => [ 40 | 'ignore_errors' => true, 41 | 'method' => 'GET', 42 | 'timeout' => $this->connectionTimeout, 43 | ]]); 44 | $headers = @\get_headers($this->url, 0, $context); 45 | 46 | if (isset($headers[0]) && 'HTTP/1.0 200 OK' === $headers[0]) { 47 | $status->setUp(true); 48 | } 49 | } catch (Exception $e) { 50 | $status->setError([ 51 | 'code' => $e->getCode(), 52 | 'message' => $e->getMessage(), 53 | ]); 54 | } 55 | 56 | return $status; 57 | } 58 | 59 | private function normilizeUrl($url): string 60 | { 61 | $parsedUrl = \parse_url($url); 62 | $scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'].'://' : 'http://'; 63 | $host = isset($parsedUrl['host']) ? $parsedUrl['host'] : ''; 64 | $port = isset($parsedUrl['port']) ? ':'.$parsedUrl['port'] : ''; 65 | $user = isset($parsedUrl['user']) ? $parsedUrl['user'] : ''; 66 | $pass = isset($parsedUrl['pass']) ? ':'.$parsedUrl['pass'] : ''; 67 | $pass = ($user || $pass) ? "{$pass}@" : ''; 68 | $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; 69 | $query = isset($parsedUrl['query']) ? '?'.$parsedUrl['query'] : ''; 70 | $fragment = isset($parsedUrl['fragment']) ? '#'.$parsedUrl['fragment'] : ''; 71 | 72 | return "{$scheme}{$user}{$pass}{$host}{$port}{$path}{$query}{$fragment}"; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Checks/PDOCheck.php: -------------------------------------------------------------------------------- 1 | dsn = $dsn; 39 | $this->username = $username; 40 | $this->password = $password; 41 | $this->driverOptions = $driverOptions; 42 | } 43 | 44 | public function getStatus(): Status 45 | { 46 | $status = new Status(); 47 | 48 | try { 49 | $up = $this->getPDO()->query('SELECT 1;')->execute(); 50 | $status->setUp($up); 51 | } catch (\PDOException $e) { 52 | $status->setUp(false); 53 | $status->setError([ 54 | 'code' => $e->getCode(), 55 | 'message' => $e->getMessage(), 56 | ]); 57 | } 58 | 59 | return $status; 60 | } 61 | 62 | private function getPDO(): PDO 63 | { 64 | return new PDO($this->dsn, $this->username, $this->password, $this->driverOptions); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Checks/PredisCheck.php: -------------------------------------------------------------------------------- 1 | client = $client; 21 | } 22 | 23 | public function getStatus(): Status 24 | { 25 | $status = new Status(); 26 | 27 | try { 28 | $this->client->connect(); 29 | $pong = (string) $this->client->ping(); 30 | $status->setUp('PONG' === $pong); 31 | } catch (Exception $e) { 32 | $status->setError([ 33 | 'code' => $e->getCode(), 34 | 'message' => $e->getMessage(), 35 | ]); 36 | } 37 | 38 | $this->client->disconnect(); 39 | 40 | return $status; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Checks/RedisCheck.php: -------------------------------------------------------------------------------- 1 | socket = $socket; 41 | } 42 | 43 | public function setAuth(string $password): self 44 | { 45 | $this->password = $password; 46 | 47 | return $this; 48 | } 49 | 50 | public function setConnectionTimeout(int $connectionTimeout): self 51 | { 52 | $this->connectionTimeout = $connectionTimeout; 53 | 54 | return $this; 55 | } 56 | 57 | public function setStreamTimeout(int $streamTimeout): self 58 | { 59 | $this->streamTimeout = $streamTimeout; 60 | 61 | return $this; 62 | } 63 | 64 | public function getStatus(): Status 65 | { 66 | $status = new Status(); 67 | 68 | try { 69 | $this->getClient()->connect(); 70 | 71 | if ($this->password) { 72 | $this->getClient()->write($this->getAuthCommand()); 73 | $responce = $this->getClient()->readLine(); 74 | if ('+OK' !== $responce) { 75 | throw new Exception($responce); 76 | } 77 | } 78 | 79 | $this->getClient()->write($this->getPingCommand()); 80 | $responce = $this->getClient()->readLine(); 81 | 82 | $status->setUp('+PONG' === $responce); 83 | 84 | $this->getClient()->disconnect(); 85 | } catch (Exception $e) { 86 | $status->setError([ 87 | 'code' => $e->getCode(), 88 | 'message' => $e->getMessage(), 89 | ]); 90 | } 91 | 92 | return $status; 93 | } 94 | 95 | private function getClient(): SocketClient 96 | { 97 | if ($this->client) { 98 | return $this->client; 99 | } 100 | 101 | $this->client = new SocketClient($this->socket, $this->connectionTimeout, $this->streamTimeout); 102 | 103 | return $this->client; 104 | } 105 | 106 | private function getAuthCommand(): string 107 | { 108 | $commandName = 'AUTH'; 109 | $commandLen = \mb_strlen($commandName); 110 | $command[] = "*2\r\n\${$commandLen}\r\n{$commandName}\r\n"; 111 | 112 | $passwordLen = \mb_strlen($this->password); 113 | $command[] = "\${$passwordLen}\r\n{$this->password}\r\n"; 114 | 115 | return \implode('', $command); 116 | } 117 | 118 | private function getPingCommand(): string 119 | { 120 | return "*1\r\n$4\r\nPING\r\n"; 121 | } 122 | 123 | public function __destruct() 124 | { 125 | $this->getClient()->disconnect(); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/Checks/SocketCheck.php: -------------------------------------------------------------------------------- 1 | socket = $socket; 36 | } 37 | 38 | public function setAuth(string $password): self 39 | { 40 | $this->password = $password; 41 | 42 | return $this; 43 | } 44 | 45 | public function setConnectionTimeout(int $connectionTimeout): self 46 | { 47 | $this->connectionTimeout = $connectionTimeout; 48 | 49 | return $this; 50 | } 51 | 52 | public function setStreamTimeout(int $streamTimeout): self 53 | { 54 | $this->streamTimeout = $streamTimeout; 55 | 56 | return $this; 57 | } 58 | 59 | public function getStatus(): Status 60 | { 61 | $status = new Status(); 62 | 63 | try { 64 | $this->getClient()->connect(); 65 | 66 | $this->getClient()->getChar(); 67 | 68 | $status->setUp(true); 69 | 70 | $this->getClient()->disconnect(); 71 | } catch (Exception $e) { 72 | $status->setError([ 73 | 'code' => $e->getCode(), 74 | 'message' => $e->getMessage(), 75 | ]); 76 | } 77 | 78 | return $status; 79 | } 80 | 81 | protected function getClient(): SocketClient 82 | { 83 | if ($this->client) { 84 | return $this->client; 85 | } 86 | 87 | $this->client = new SocketClient($this->socket, $this->connectionTimeout, $this->streamTimeout); 88 | 89 | return $this->client; 90 | } 91 | 92 | public function __destruct() 93 | { 94 | $this->getClient()->disconnect(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Checks/SocketConnectionCheck.php: -------------------------------------------------------------------------------- 1 | getClient()->connect(); 18 | 19 | $status->setUp(true); 20 | 21 | $this->getClient()->disconnect(); 22 | } catch (Exception $e) { 23 | $status->setError([ 24 | 'code' => $e->getCode(), 25 | 'message' => $e->getMessage(), 26 | ]); 27 | } 28 | 29 | return $status; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/SocketClient.php: -------------------------------------------------------------------------------- 1 | dsn = $dsn; 41 | $this->connectionTimeout = $connectionTimeout; 42 | $this->streamTimeout = $streamTimeout; 43 | } 44 | 45 | public function connect() 46 | { 47 | $validTransports = \stream_get_transports(); 48 | $parsed = \parse_url($this->dsn); 49 | $remoteSocket = ''; 50 | 51 | if (\in_array($parsed['scheme'] ?? null, $validTransports)) { 52 | $remoteSocket .= $parsed['scheme'].'://'; 53 | } 54 | 55 | $remoteSocket .= $parsed['host']; 56 | 57 | if ($parsed['port'] ?? null) { 58 | $remoteSocket .= ':'.$parsed['port']; 59 | } 60 | 61 | if ($parsed['path'] ?? null) { 62 | $remoteSocket .= '/'.$parsed['path']; 63 | } 64 | 65 | $this->remoteSocket = $remoteSocket; 66 | 67 | $this->socket = @\stream_socket_client( 68 | $this->remoteSocket, 69 | $errno, 70 | $errstr, 71 | $this->connectionTimeout 72 | ); 73 | 74 | if (!$this->socket) { 75 | throw new Exception("Cannot connect to {$this->remoteSocket}: {$errstr}", $errno); 76 | } 77 | } 78 | 79 | public function disconnect() 80 | { 81 | if ($this->socket) { 82 | if (!\fclose($this->socket)) { 83 | throw new Exception('Error while closing socket'); 84 | } 85 | 86 | $this->socket = null; 87 | } 88 | } 89 | 90 | public function write($str): void 91 | { 92 | \stream_set_timeout($this->socket, $this->streamTimeout); 93 | $ok = \fputs($this->socket, $str); 94 | 95 | if (false === $ok) { 96 | throw new Exception('Error while writing to socket.'); 97 | } 98 | } 99 | 100 | public function getChar(): string 101 | { 102 | \stream_set_timeout($this->socket, $this->streamTimeout); 103 | $c = \fgetc($this->socket); 104 | 105 | if (false === $c || '' === $c) { 106 | throw new Exception('Error while reading char from socket.'); 107 | } 108 | 109 | return $c; 110 | } 111 | 112 | public function readLine(): string 113 | { 114 | return $this->readTill("\r\n"); 115 | } 116 | 117 | public function readTill(string $term): string 118 | { 119 | if (!$this->socket) { 120 | throw new Exception('Open connection first', 1); 121 | } 122 | 123 | \stream_set_timeout($this->socket, $this->streamTimeout); 124 | 125 | $termLen = \mb_strlen($term); 126 | $value = ''; 127 | do { 128 | $c = \fgets($this->socket); 129 | 130 | if (false === $c || '' === $c) { 131 | throw new Exception('Error while reading line from socket.'); 132 | } 133 | 134 | $value .= $c; 135 | } while ($term !== \mb_substr($value, -$termLen)); 136 | 137 | return \mb_substr($value, 0, -$termLen); 138 | } 139 | 140 | public function __destruct() 141 | { 142 | $this->disconnect(); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/Status.php: -------------------------------------------------------------------------------- 1 | up; 27 | } 28 | 29 | public function setUp(bool $up) 30 | { 31 | $this->up = $up; 32 | } 33 | 34 | public function setError(array $error) 35 | { 36 | $this->error = $error; 37 | } 38 | 39 | public function getError(): ?array 40 | { 41 | return $this->error; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/Checks/AllInOneCheckTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(CheckInterface::class, $check); 17 | } 18 | 19 | public function test_it_is_up_when_empty() 20 | { 21 | $check = new AllInOneCheck(); 22 | 23 | $this->assertTrue($check->getStatus()->isUp()); 24 | } 25 | 26 | public function test_it_is_up_if_every_child_is_up() 27 | { 28 | $check = new AllInOneCheck(); 29 | 30 | $check->add($this->newCheckMock(true)); 31 | $check->add($this->newCheckMock(true)); 32 | 33 | $this->assertTrue($check->getStatus()->isUp()); 34 | } 35 | 36 | public function test_it_is_down_if_some_of_child_is_down() 37 | { 38 | $check = new AllInOneCheck(); 39 | 40 | $check->add($this->newCheckMock(true)); 41 | $check->add($this->newCheckMock(false)); 42 | $check->add($this->newCheckMock(true)); 43 | 44 | $this->assertFalse($check->getStatus()->isUp()); 45 | } 46 | 47 | public function test_it_collects_errors() 48 | { 49 | $check = new AllInOneCheck(); 50 | 51 | $check->add($this->newCheckMock(false, ['foo' => 1])); 52 | $check->add($this->newCheckMock(false, ['bar' => 2])); 53 | $check->add($this->newCheckMock(true)); 54 | 55 | $this->assertFalse($check->getStatus()->isUp()); 56 | $this->assertEquals([['foo' => 1], ['bar' => 2]], $check->getStatus()->getError()); 57 | } 58 | 59 | public function newCheckMock(bool $isUp, $error = null): CheckInterface 60 | { 61 | $check = $this->createMock(CheckInterface::class); 62 | $status = new Status(); 63 | $status->setUp($isUp); 64 | if ($error) { 65 | $status->setError($error); 66 | } 67 | $check->method('getStatus')->willReturn($status); 68 | 69 | return $check; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/Checks/HttpCheckTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($check->getStatus()->isUp()); 17 | } 18 | 19 | public function test_it_normilize_url() 20 | { 21 | $check = new HttpCheck('localhost:8005/get_ok'); 22 | 23 | $this->assertTrue($check->getStatus()->isUp()); 24 | } 25 | 26 | public function test_get_fails() 27 | { 28 | $check = new HttpCheck('localhost:8005/get_fail'); 29 | 30 | $this->assertFalse($check->getStatus()->isUp()); 31 | } 32 | 33 | public function test_get_fails_when_connecting_to_mysql() 34 | { 35 | $check = new HttpCheck('http://localhost:8001'); 36 | 37 | $this->assertFalse($check->getStatus()->isUp()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/Checks/PDOCheckTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($check->getStatus()->isUp()); 17 | } 18 | 19 | public function test_mysql57_is_down_on_wrong_credentials() 20 | { 21 | // no password 22 | $check = new PDOCheck('mysql:dbname=test_db;host=localhost:8001', 'test_user'); 23 | $this->assertFalse($check->getStatus()->isUp()); 24 | $this->assertEquals(1045, $check->getStatus()->getError()['code']); 25 | 26 | // wrong password 27 | $check = new PDOCheck('mysql:dbname=test_db;host=localhost:8001', 'test_user', '321'); 28 | $this->assertFalse($check->getStatus()->isUp()); 29 | $this->assertEquals(1045, $check->getStatus()->getError()['code']); 30 | 31 | // wrong host 32 | $check = new PDOCheck('mysql:dbname=test_db;host=fake:8001', 'test_user', 'test_pass'); 33 | $this->assertFalse($check->getStatus()->isUp()); 34 | $this->assertEquals(2002, $check->getStatus()->getError()['code']); 35 | } 36 | 37 | public function test_postgres13_is_up() 38 | { 39 | $check = new PDOCheck('pgsql:host=localhost;port=8002;dbname=test_db', 'test_user', '123'); 40 | 41 | $this->assertTrue($check->getStatus()->isUp()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/Checks/PredisCheckTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($check->getStatus()->isUp()); 18 | } 19 | 20 | public function test_fails_if_host_not_exists() 21 | { 22 | $check = new PredisCheck(new Client('localhost:8001')); 23 | 24 | $this->assertFalse($check->getStatus()->isUp()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/Checks/RedisCheckTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($check->getStatus()->isUp()); 17 | } 18 | 19 | public function test_redis_with_password_is_up() 20 | { 21 | $check = (new RedisCheck('localhost:8004'))->setAuth('test_pass'); 22 | 23 | $this->assertTrue($check->getStatus()->isUp()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/Checks/SocketCheckTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($check->getStatus()->isUp()); 17 | } 18 | 19 | public function test_fails_if_host_not_exists() 20 | { 21 | $check = new SocketCheck('127.0.0.2:8001'); 22 | 23 | $this->assertFalse($check->getStatus()->isUp()); 24 | } 25 | 26 | public function test_fails_if_wrong_port() 27 | { 28 | $check = new SocketCheck('127.0.0.1:80999'); 29 | 30 | $this->assertFalse($check->getStatus()->isUp()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Checks/SocketConnectionCheckTest.php: -------------------------------------------------------------------------------- 1 | assertTrue($check->getStatus()->isUp()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/Resource/jmock/one.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "request": { 4 | "method": "GET", 5 | "url": "/get_ok" 6 | }, 7 | "response": { 8 | "code": 200, 9 | "body": "OK" 10 | } 11 | }, 12 | { 13 | "request": { 14 | "method": "GET", 15 | "url": "/get_fail" 16 | }, 17 | "response": { 18 | "code": 503, 19 | "body": "FAIL" 20 | } 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /tests/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | mysql57: 5 | image: mysql:5.7 6 | ports: 7 | - 8001:3306 8 | environment: 9 | MYSQL_ROOT_PASSWORD: 123 10 | MYSQL_DATABASE: test_db 11 | MYSQL_USER: test_user 12 | MYSQL_PASSWORD: test_pass 13 | postgres13: 14 | image: postgres:13 15 | ports: 16 | - 8002:5432 17 | environment: 18 | POSTGRES_PASSWORD: 123 19 | POSTGRES_USER: test_user 20 | POSTGRES_DB: test_db 21 | redis: 22 | image: redis:6.0.9-alpine 23 | ports: 24 | - 8003:6379 25 | redis_with_password: 26 | image: redis:6.0.9-alpine 27 | command: redis-server --requirepass test_pass 28 | ports: 29 | - 8004:6379 30 | jmock: 31 | image: fullpipe/jmock 32 | ports: 33 | - 8005:9090 34 | volumes: 35 | - ./Resource/jmock:/mocks 36 | rabbitmq: 37 | image: rabbitmq:3.8.9-alpine 38 | ports: 39 | - 8006:5672 40 | -------------------------------------------------------------------------------- /tests/realtime_test.php: -------------------------------------------------------------------------------- 1 | setCode(function (InputInterface $input, OutputInterface $output) { 19 | $checks = []; 20 | 21 | $checks['mysql 5.7'] = new PDOCheck('mysql:dbname=test_db;host=localhost:8001', 'test_user', 'test_pass'); 22 | $checks['mysql 5.7 [telnet]'] = new SocketCheck('localhost:8001'); 23 | $checks['postgres13'] = new PDOCheck('pgsql:host=localhost;port=8002;dbname=test_db', 'test_user', '123'); 24 | 25 | $predis = new PredisClient('localhost:8003'); 26 | $checks['redis [predis]'] = new PredisCheck($predis); 27 | 28 | $checks['redis [raw]'] = new RedisCheck('localhost:8003'); 29 | $checks['redis_with_password [raw]'] = (new RedisCheck('localhost:8004'))->setAuth('test_pass'); 30 | $checks['http'] = new HttpCheck('http://localhost:8005/get_ok'); 31 | 32 | $checks['rabbitmq [socket]'] = new SocketConnectionCheck('localhost:8006'); 33 | 34 | $table = new Table($output); 35 | $table->setHeaders(\array_keys($checks)); 36 | $table->setHorizontal(true); 37 | 38 | $table->render(); 39 | 40 | $tableHeight = \count($checks) + 2; 41 | $stats = []; 42 | $ticks = 0; 43 | 44 | while (true) { 45 | ++$ticks; 46 | $table->setFooterTitle("ticks: {$ticks}"); 47 | 48 | $rowStats = []; 49 | foreach ($checks as $check) { 50 | $rowStats[] = $check->getStatus()->isUp() ? '🌞' : '🧨'; 51 | } 52 | 53 | if (\count($stats) > 15) { 54 | \array_shift($stats); 55 | } 56 | 57 | $stats[] = $rowStats; 58 | 59 | $table->setRows($stats); 60 | echo "\033[{$tableHeight}A"; 61 | $table->render(); 62 | 63 | \sleep(1); 64 | } 65 | }) 66 | ->run(); 67 | --------------------------------------------------------------------------------