├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── phpunit.xml └── src ├── Async ├── AbstractConnection.php ├── Client.php ├── Connection.php ├── Domain.php └── Session.php ├── Blocking ├── BlockTrait.php ├── Client.php ├── Connection.php ├── Domain.php └── EventHandlerTrait.php ├── ClientInterface.php ├── ConnectionInterface.php ├── DomainInterface.php └── Exception └── ProtocolErrorException.php /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 John D. Moore 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jmoo/chrome-react 2 | 3 | 4 | [![Build Status](https://travis-ci.com/jmoo/chrome-reactphp.svg?branch=master)](https://travis-ci.com/jmoo/chrome-reactphp) 5 | 6 | [DevTools Api](https://chromedevtools.github.io/devtools-protocol/tot) 7 | 8 | Fully async, low-level client for the Chrome DevTools Protocol using ReactPHP 9 | 10 | 11 | *Warning: Experimental! Expect large breaking changes, instability, and lack of documentation until there is a tagged version* 12 | 13 | ### Installation 14 | 15 | ```bash 16 | $ composer require jmoo/chrome-react 17 | ``` 18 | 19 | ### Getting Started 20 | #### Running Chrome 21 | ```bash 22 | $ chrome --headless --disable-gpu --remote-debugging-port=9222 23 | ``` 24 | 25 | #### Navigate to a page (synchronously) 26 | The blocking client runs the event loop while awaiting completion of each task. 27 | This allows you to write normal synchronous code while still responding to asynchronous events. 28 | ```php 29 | $chrome = new \Jmoo\React\Chrome\Blocking\Client; 30 | $url = $chrome->new()->webSocketDebuggerUrl; 31 | $tab = $chrome->connect($url); 32 | 33 | $tab->Page->enable(); 34 | $tab->Page->navigate(['url' => 'https://www.chromium.org/']); 35 | $tab->disconnect(); 36 | ``` 37 | 38 | #### Navigate to a page (asynchronously) 39 | The async client returns Promises for each command. 40 | ```php 41 | $loop = \React\EventLoop\Factory::create(); 42 | $chrome = new \Jmoo\React\Chrome\Async\Client($loop); 43 | 44 | $chrome 45 | ->new() 46 | ->then(function ($page) use ($chrome) { 47 | return $chrome->connect($page->webSocketDebuggerUrl); 48 | }) 49 | ->then(function ($c) { 50 | return \React\Promise\all([ 51 | $c, 52 | $c->Page->enable(), 53 | $c->Page->navigate(['url' => 'https://www.google.com']) 54 | ]); 55 | }) 56 | ->then(function ($result) { 57 | list($c) = $result; 58 | $c->disconnect(); 59 | }); 60 | 61 | $loop->run(); 62 | ``` 63 | 64 | #### Navigate to a page (coroutines) 65 | The async client can be used with amphp coroutines using ```amphp/react-adapter``` 66 | ```php 67 | \Amp\Loop::run(function() { 68 | $chrome = new \Jmoo\React\Chrome\Async\Client(ReactAdapter::get()); 69 | 70 | $tabInfo = yield $chrome->new(); 71 | $tab = yield $chrome->connect($tabInfo->webSocketDebuggerUrl); 72 | 73 | yield $tab->Page->enable(); 74 | yield $tab->Page->navigate(['url' => 'https://news.ycombinator.com/']); 75 | $tab->disconnect(); 76 | }); 77 | ``` 78 | 79 | #### Using an existing event loop with the blocking client 80 | ```php 81 | // any existing event loop 82 | $loop = \React\EventLoop\Factory::create(); 83 | 84 | // create a new async client with event loop 85 | $async = new \Jmoo\React\Chrome\Async\Client($loop); 86 | 87 | // create a new blocking client using async client 88 | $chrome = new \Jmoo\React\Chrome\Blocking\Client($async); 89 | 90 | ``` 91 | 92 | ### Usage 93 | 94 | #### Configuration 95 | ```php 96 | # Default options 97 | $client = (new Client)->withOptions([ 98 | 'host' => '127.0.0.1', 99 | 'port' => 9222, 100 | 'ssl' => false, 101 | 'timeout' => 30 // blocking client only 102 | ]); 103 | 104 | # Using a custom event-loop and connector 105 | $asyncClient = new \Jmoo\React\Chrome\Async\Client($loop, $connector); 106 | $blockingClient = new \Jmoo\React\Chrome\Blocking\Client($asyncClient); 107 | 108 | ``` 109 | 110 | #### Domains 111 | ```php 112 | $client = new \Jmoo\React\Chrome\Blocking\Client; 113 | $c = $client->connect($client->new()->webSocketDebuggerUrl); 114 | 115 | // getting a domain accessor 116 | $page = $c->Page; // with magic method 117 | $page = $c->getDomain('Page'); // directly 118 | 119 | // enable events and retrieve multiple domain accessors at the same time 120 | list($page, $network, $log) = $c->enable(['Page', 'Network', 'Log']); 121 | 122 | ``` 123 | 124 | #### Methods 125 | ```php 126 | $client = new \Jmoo\React\Chrome\Blocking\Client; 127 | $c = $client->connect($client->new()->webSocketDebuggerUrl); 128 | 129 | // executing a method using the domain accessor 130 | $c->Page->navigate(['url' => 'http://jmoo.io']); // with magic method 131 | $c->Page->send('navigate', ['url' => 'http://jmoo.io']); // directly 132 | 133 | // without using domain accessor 134 | $c->send('Page.navigate', ['url' => 'http://jmoo.io']); 135 | 136 | ``` 137 | 138 | #### Events 139 | ```php 140 | $client = new \Jmoo\React\Chrome\Blocking\Client; 141 | $c = $client->connect($client->new()->webSocketDebuggerUrl); 142 | 143 | // events must be enabled 144 | $c->Page->enable(); 145 | 146 | $c->Page->on('domContentEventFired', function() use ($c) { 147 | $c->disconnect(); 148 | }); 149 | 150 | // pause execution until disconnect (blocking client only) 151 | $c->waitForDisconnect(); 152 | 153 | ``` 154 | 155 | #### Sessions 156 | ```php 157 | $client = new \Jmoo\React\Chrome\Blocking\Client; 158 | $c = $client->connect($client->version()->webSocketDebuggerUrl); 159 | 160 | $target = $c->send('Target.createTarget', ['url' => 'about:blank']); 161 | $session = $c->createSession($target->targetId); 162 | $session->Page->enable(); 163 | ``` -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jmoo/chrome-react", 3 | "description": "Async, low-level client for the Chrome DevTools Protocol using ReactPHP", 4 | "keywords": ["ReactPHP", "async", "chrome", "cdp", "browser", "headless", "client"], 5 | "type": "library", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "John D. Moore", 10 | "email": "me@jmoo.io" 11 | } 12 | ], 13 | "support": { 14 | "issues": "https://github.com/jmoo/chrome-reactphp/issues", 15 | "source": "https://github.com/jmoo/chrome-reactphp" 16 | }, 17 | "require": { 18 | "php": "^7.1", 19 | "ratchet/pawl": "^0.3.2", 20 | "clue/block-react": "^1.3", 21 | "clue/buzz-react": "^2.3", 22 | "react/promise": "^2.7", 23 | "react/event-loop": "^0.4.3||^0.5.2||^1.0" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "Jmoo\\React\\Chrome\\": "src/" 28 | } 29 | }, 30 | "autoload-dev": { 31 | "psr-4": { 32 | "Jmoo\\React\\Chrome\\Tests\\": "tests/" 33 | } 34 | }, 35 | "minimum-stability": "stable", 36 | "require-dev": { 37 | "phpunit/phpunit": "^6.3", 38 | "monolog/monolog": "^1.23", 39 | "amphp/amp": "^2.0", 40 | "amphp/react-adapter": "^1.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /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#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "4d3d51eee4d7ca027f02c276ba84104b", 8 | "packages": [ 9 | { 10 | "name": "clue/block-react", 11 | "version": "v1.3.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/clue/reactphp-block.git", 15 | "reference": "a4a5cd64ded3b15affa168a2419fa4eda08b96aa" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/clue/reactphp-block/zipball/a4a5cd64ded3b15affa168a2419fa4eda08b96aa", 20 | "reference": "a4a5cd64ded3b15affa168a2419fa4eda08b96aa", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=5.3", 25 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5", 26 | "react/promise": "^2.7 || ^1.2.1", 27 | "react/promise-timer": "^1.5" 28 | }, 29 | "require-dev": { 30 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35" 31 | }, 32 | "type": "library", 33 | "autoload": { 34 | "files": [ 35 | "src/functions.php" 36 | ] 37 | }, 38 | "notification-url": "https://packagist.org/downloads/", 39 | "license": [ 40 | "MIT" 41 | ], 42 | "authors": [ 43 | { 44 | "name": "Christian Lück", 45 | "email": "christian@lueck.tv" 46 | } 47 | ], 48 | "description": "Lightweight library that eases integrating async components built for ReactPHP in a traditional, blocking environment.", 49 | "homepage": "https://github.com/clue/reactphp-block", 50 | "keywords": [ 51 | "async", 52 | "await", 53 | "blocking", 54 | "event loop", 55 | "promise", 56 | "reactphp", 57 | "sleep", 58 | "synchronous" 59 | ], 60 | "time": "2018-06-14T08:50:53+00:00" 61 | }, 62 | { 63 | "name": "clue/buzz-react", 64 | "version": "v2.3.0", 65 | "source": { 66 | "type": "git", 67 | "url": "https://github.com/clue/php-buzz-react.git", 68 | "reference": "c37408fc5265dd853c31aea4e0b409f8c8d7af11" 69 | }, 70 | "dist": { 71 | "type": "zip", 72 | "url": "https://api.github.com/repos/clue/php-buzz-react/zipball/c37408fc5265dd853c31aea4e0b409f8c8d7af11", 73 | "reference": "c37408fc5265dd853c31aea4e0b409f8c8d7af11", 74 | "shasum": "" 75 | }, 76 | "require": { 77 | "php": ">=5.3", 78 | "psr/http-message": "^1.0", 79 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3", 80 | "react/http-client": "^0.5.8", 81 | "react/promise": "^2.2.1 || ^1.2.1", 82 | "react/promise-stream": "^1.0 || ^0.1.1", 83 | "react/socket": "^1.0 || ^0.8.4", 84 | "react/stream": "^1.0 || ^0.7", 85 | "ringcentral/psr7": "^1.2" 86 | }, 87 | "require-dev": { 88 | "clue/block-react": "^1.0", 89 | "clue/socks-react": "^0.8", 90 | "phpunit/phpunit": "^7.0 || ^6.4 || ^5.7 || ^4.8.35", 91 | "react/http": "^0.8" 92 | }, 93 | "type": "library", 94 | "autoload": { 95 | "psr-4": { 96 | "Clue\\React\\Buzz\\": "src/" 97 | } 98 | }, 99 | "notification-url": "https://packagist.org/downloads/", 100 | "license": [ 101 | "MIT" 102 | ], 103 | "authors": [ 104 | { 105 | "name": "Christian Lück", 106 | "email": "christian@lueck.tv" 107 | } 108 | ], 109 | "description": "Simple, async PSR-7 HTTP client for concurrently processing any number of HTTP requests, built on top of ReactPHP", 110 | "homepage": "https://github.com/clue/php-buzz-react", 111 | "keywords": [ 112 | "async", 113 | "http", 114 | "http client", 115 | "psr-7", 116 | "reactphp" 117 | ], 118 | "time": "2018-02-09T14:08:41+00:00" 119 | }, 120 | { 121 | "name": "evenement/evenement", 122 | "version": "v3.0.1", 123 | "source": { 124 | "type": "git", 125 | "url": "https://github.com/igorw/evenement.git", 126 | "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7" 127 | }, 128 | "dist": { 129 | "type": "zip", 130 | "url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7", 131 | "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7", 132 | "shasum": "" 133 | }, 134 | "require": { 135 | "php": ">=7.0" 136 | }, 137 | "require-dev": { 138 | "phpunit/phpunit": "^6.0" 139 | }, 140 | "type": "library", 141 | "autoload": { 142 | "psr-0": { 143 | "Evenement": "src" 144 | } 145 | }, 146 | "notification-url": "https://packagist.org/downloads/", 147 | "license": [ 148 | "MIT" 149 | ], 150 | "authors": [ 151 | { 152 | "name": "Igor Wiedler", 153 | "email": "igor@wiedler.ch" 154 | } 155 | ], 156 | "description": "Événement is a very simple event dispatching library for PHP", 157 | "keywords": [ 158 | "event-dispatcher", 159 | "event-emitter" 160 | ], 161 | "time": "2017-07-23T21:35:13+00:00" 162 | }, 163 | { 164 | "name": "guzzlehttp/psr7", 165 | "version": "1.4.2", 166 | "source": { 167 | "type": "git", 168 | "url": "https://github.com/guzzle/psr7.git", 169 | "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" 170 | }, 171 | "dist": { 172 | "type": "zip", 173 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", 174 | "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", 175 | "shasum": "" 176 | }, 177 | "require": { 178 | "php": ">=5.4.0", 179 | "psr/http-message": "~1.0" 180 | }, 181 | "provide": { 182 | "psr/http-message-implementation": "1.0" 183 | }, 184 | "require-dev": { 185 | "phpunit/phpunit": "~4.0" 186 | }, 187 | "type": "library", 188 | "extra": { 189 | "branch-alias": { 190 | "dev-master": "1.4-dev" 191 | } 192 | }, 193 | "autoload": { 194 | "psr-4": { 195 | "GuzzleHttp\\Psr7\\": "src/" 196 | }, 197 | "files": [ 198 | "src/functions_include.php" 199 | ] 200 | }, 201 | "notification-url": "https://packagist.org/downloads/", 202 | "license": [ 203 | "MIT" 204 | ], 205 | "authors": [ 206 | { 207 | "name": "Michael Dowling", 208 | "email": "mtdowling@gmail.com", 209 | "homepage": "https://github.com/mtdowling" 210 | }, 211 | { 212 | "name": "Tobias Schultze", 213 | "homepage": "https://github.com/Tobion" 214 | } 215 | ], 216 | "description": "PSR-7 message implementation that also provides common utility methods", 217 | "keywords": [ 218 | "http", 219 | "message", 220 | "request", 221 | "response", 222 | "stream", 223 | "uri", 224 | "url" 225 | ], 226 | "time": "2017-03-20T17:10:46+00:00" 227 | }, 228 | { 229 | "name": "psr/http-message", 230 | "version": "1.0.1", 231 | "source": { 232 | "type": "git", 233 | "url": "https://github.com/php-fig/http-message.git", 234 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 235 | }, 236 | "dist": { 237 | "type": "zip", 238 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", 239 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 240 | "shasum": "" 241 | }, 242 | "require": { 243 | "php": ">=5.3.0" 244 | }, 245 | "type": "library", 246 | "extra": { 247 | "branch-alias": { 248 | "dev-master": "1.0.x-dev" 249 | } 250 | }, 251 | "autoload": { 252 | "psr-4": { 253 | "Psr\\Http\\Message\\": "src/" 254 | } 255 | }, 256 | "notification-url": "https://packagist.org/downloads/", 257 | "license": [ 258 | "MIT" 259 | ], 260 | "authors": [ 261 | { 262 | "name": "PHP-FIG", 263 | "homepage": "http://www.php-fig.org/" 264 | } 265 | ], 266 | "description": "Common interface for HTTP messages", 267 | "homepage": "https://github.com/php-fig/http-message", 268 | "keywords": [ 269 | "http", 270 | "http-message", 271 | "psr", 272 | "psr-7", 273 | "request", 274 | "response" 275 | ], 276 | "time": "2016-08-06T14:39:51+00:00" 277 | }, 278 | { 279 | "name": "ratchet/pawl", 280 | "version": "v0.3.2", 281 | "source": { 282 | "type": "git", 283 | "url": "https://github.com/ratchetphp/Pawl.git", 284 | "reference": "85ca3b4a85254cf2ac4309ef42d427820770ae31" 285 | }, 286 | "dist": { 287 | "type": "zip", 288 | "url": "https://api.github.com/repos/ratchetphp/Pawl/zipball/85ca3b4a85254cf2ac4309ef42d427820770ae31", 289 | "reference": "85ca3b4a85254cf2ac4309ef42d427820770ae31", 290 | "shasum": "" 291 | }, 292 | "require": { 293 | "evenement/evenement": "^3.0 || ^2.0", 294 | "php": ">=5.4", 295 | "ratchet/rfc6455": "^0.2.3", 296 | "react/socket": "^1.0 || ^0.8 || ^0.7" 297 | }, 298 | "require-dev": { 299 | "phpunit/phpunit": "~4.8" 300 | }, 301 | "suggest": { 302 | "reactivex/rxphp": "~2.0" 303 | }, 304 | "type": "library", 305 | "autoload": { 306 | "psr-4": { 307 | "Ratchet\\Client\\": "src" 308 | }, 309 | "files": [ 310 | "src/functions_include.php" 311 | ] 312 | }, 313 | "notification-url": "https://packagist.org/downloads/", 314 | "license": [ 315 | "MIT" 316 | ], 317 | "description": "Asynchronous WebSocket client", 318 | "keywords": [ 319 | "Ratchet", 320 | "async", 321 | "client", 322 | "websocket", 323 | "websocket client" 324 | ], 325 | "time": "2018-05-22T21:45:08+00:00" 326 | }, 327 | { 328 | "name": "ratchet/rfc6455", 329 | "version": "0.2.4", 330 | "source": { 331 | "type": "git", 332 | "url": "https://github.com/ratchetphp/RFC6455.git", 333 | "reference": "1612f528c3496ad06e910d0f8b6f16ab97696706" 334 | }, 335 | "dist": { 336 | "type": "zip", 337 | "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/1612f528c3496ad06e910d0f8b6f16ab97696706", 338 | "reference": "1612f528c3496ad06e910d0f8b6f16ab97696706", 339 | "shasum": "" 340 | }, 341 | "require": { 342 | "guzzlehttp/psr7": "^1.0", 343 | "php": ">=5.4.2" 344 | }, 345 | "require-dev": { 346 | "phpunit/phpunit": "4.8.*", 347 | "react/http": "^0.4.1", 348 | "react/socket-client": "^0.4.3" 349 | }, 350 | "type": "library", 351 | "autoload": { 352 | "psr-4": { 353 | "Ratchet\\RFC6455\\": "src" 354 | } 355 | }, 356 | "notification-url": "https://packagist.org/downloads/", 357 | "license": [ 358 | "MIT" 359 | ], 360 | "authors": [ 361 | { 362 | "name": "Chris Boden", 363 | "email": "cboden@gmail.com", 364 | "role": "Developer" 365 | } 366 | ], 367 | "description": "RFC6455 WebSocket protocol handler", 368 | "homepage": "http://socketo.me", 369 | "keywords": [ 370 | "WebSockets", 371 | "rfc6455", 372 | "websocket" 373 | ], 374 | "time": "2018-05-02T14:52:00+00:00" 375 | }, 376 | { 377 | "name": "react/cache", 378 | "version": "v0.5.0", 379 | "source": { 380 | "type": "git", 381 | "url": "https://github.com/reactphp/cache.git", 382 | "reference": "7d7da7fb7574d471904ba357b39bbf110ccdbf66" 383 | }, 384 | "dist": { 385 | "type": "zip", 386 | "url": "https://api.github.com/repos/reactphp/cache/zipball/7d7da7fb7574d471904ba357b39bbf110ccdbf66", 387 | "reference": "7d7da7fb7574d471904ba357b39bbf110ccdbf66", 388 | "shasum": "" 389 | }, 390 | "require": { 391 | "php": ">=5.3.0", 392 | "react/promise": "~2.0|~1.1" 393 | }, 394 | "require-dev": { 395 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35" 396 | }, 397 | "type": "library", 398 | "autoload": { 399 | "psr-4": { 400 | "React\\Cache\\": "src/" 401 | } 402 | }, 403 | "notification-url": "https://packagist.org/downloads/", 404 | "license": [ 405 | "MIT" 406 | ], 407 | "description": "Async, Promise-based cache interface for ReactPHP", 408 | "keywords": [ 409 | "cache", 410 | "caching", 411 | "promise", 412 | "reactphp" 413 | ], 414 | "time": "2018-06-25T12:52:40+00:00" 415 | }, 416 | { 417 | "name": "react/dns", 418 | "version": "v0.4.15", 419 | "source": { 420 | "type": "git", 421 | "url": "https://github.com/reactphp/dns.git", 422 | "reference": "319e110a436d26a2fa137cfa3ef2063951715794" 423 | }, 424 | "dist": { 425 | "type": "zip", 426 | "url": "https://api.github.com/repos/reactphp/dns/zipball/319e110a436d26a2fa137cfa3ef2063951715794", 427 | "reference": "319e110a436d26a2fa137cfa3ef2063951715794", 428 | "shasum": "" 429 | }, 430 | "require": { 431 | "php": ">=5.3.0", 432 | "react/cache": "^0.5 || ^0.4 || ^0.3", 433 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5", 434 | "react/promise": "^2.1 || ^1.2.1", 435 | "react/promise-timer": "^1.2", 436 | "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.5" 437 | }, 438 | "require-dev": { 439 | "clue/block-react": "^1.2", 440 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35" 441 | }, 442 | "type": "library", 443 | "autoload": { 444 | "psr-4": { 445 | "React\\Dns\\": "src" 446 | } 447 | }, 448 | "notification-url": "https://packagist.org/downloads/", 449 | "license": [ 450 | "MIT" 451 | ], 452 | "description": "Async DNS resolver for ReactPHP", 453 | "keywords": [ 454 | "async", 455 | "dns", 456 | "dns-resolver", 457 | "reactphp" 458 | ], 459 | "time": "2018-07-02T12:17:56+00:00" 460 | }, 461 | { 462 | "name": "react/event-loop", 463 | "version": "v0.4.3", 464 | "source": { 465 | "type": "git", 466 | "url": "https://github.com/reactphp/event-loop.git", 467 | "reference": "8bde03488ee897dc6bb3d91e4e17c353f9c5252f" 468 | }, 469 | "dist": { 470 | "type": "zip", 471 | "url": "https://api.github.com/repos/reactphp/event-loop/zipball/8bde03488ee897dc6bb3d91e4e17c353f9c5252f", 472 | "reference": "8bde03488ee897dc6bb3d91e4e17c353f9c5252f", 473 | "shasum": "" 474 | }, 475 | "require": { 476 | "php": ">=5.4.0" 477 | }, 478 | "require-dev": { 479 | "phpunit/phpunit": "~4.8" 480 | }, 481 | "suggest": { 482 | "ext-event": "~1.0", 483 | "ext-libev": "*", 484 | "ext-libevent": ">=0.1.0" 485 | }, 486 | "type": "library", 487 | "autoload": { 488 | "psr-4": { 489 | "React\\EventLoop\\": "src" 490 | } 491 | }, 492 | "notification-url": "https://packagist.org/downloads/", 493 | "license": [ 494 | "MIT" 495 | ], 496 | "description": "Event loop abstraction layer that libraries can use for evented I/O.", 497 | "keywords": [ 498 | "asynchronous", 499 | "event-loop" 500 | ], 501 | "time": "2017-04-27T10:56:23+00:00" 502 | }, 503 | { 504 | "name": "react/http-client", 505 | "version": "v0.5.9", 506 | "source": { 507 | "type": "git", 508 | "url": "https://github.com/reactphp/http-client.git", 509 | "reference": "f8e81a022b61938e0b37c94c6351fc170b7d87f6" 510 | }, 511 | "dist": { 512 | "type": "zip", 513 | "url": "https://api.github.com/repos/reactphp/http-client/zipball/f8e81a022b61938e0b37c94c6351fc170b7d87f6", 514 | "reference": "f8e81a022b61938e0b37c94c6351fc170b7d87f6", 515 | "shasum": "" 516 | }, 517 | "require": { 518 | "evenement/evenement": "^3.0 || ^2.0 || ^1.0", 519 | "php": ">=5.3.0", 520 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3", 521 | "react/promise": "^2.1 || ^1.2.1", 522 | "react/socket": "^1.0 || ^0.8.4", 523 | "react/stream": "^1.0 || ^0.7.1", 524 | "ringcentral/psr7": "^1.2" 525 | }, 526 | "require-dev": { 527 | "clue/block-react": "^1.2", 528 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35", 529 | "react/promise-stream": "^1.1" 530 | }, 531 | "type": "library", 532 | "autoload": { 533 | "psr-4": { 534 | "React\\HttpClient\\": "src" 535 | } 536 | }, 537 | "notification-url": "https://packagist.org/downloads/", 538 | "license": [ 539 | "MIT" 540 | ], 541 | "description": "Event-driven, streaming HTTP client for ReactPHP", 542 | "keywords": [ 543 | "http" 544 | ], 545 | "time": "2018-04-10T11:38:54+00:00" 546 | }, 547 | { 548 | "name": "react/promise", 549 | "version": "v2.7.0", 550 | "source": { 551 | "type": "git", 552 | "url": "https://github.com/reactphp/promise.git", 553 | "reference": "f4edc2581617431aea50430749db55cc3fc031b3" 554 | }, 555 | "dist": { 556 | "type": "zip", 557 | "url": "https://api.github.com/repos/reactphp/promise/zipball/f4edc2581617431aea50430749db55cc3fc031b3", 558 | "reference": "f4edc2581617431aea50430749db55cc3fc031b3", 559 | "shasum": "" 560 | }, 561 | "require": { 562 | "php": ">=5.4.0" 563 | }, 564 | "require-dev": { 565 | "phpunit/phpunit": "~4.8" 566 | }, 567 | "type": "library", 568 | "autoload": { 569 | "psr-4": { 570 | "React\\Promise\\": "src/" 571 | }, 572 | "files": [ 573 | "src/functions_include.php" 574 | ] 575 | }, 576 | "notification-url": "https://packagist.org/downloads/", 577 | "license": [ 578 | "MIT" 579 | ], 580 | "authors": [ 581 | { 582 | "name": "Jan Sorgalla", 583 | "email": "jsorgalla@gmail.com" 584 | } 585 | ], 586 | "description": "A lightweight implementation of CommonJS Promises/A for PHP", 587 | "keywords": [ 588 | "promise", 589 | "promises" 590 | ], 591 | "time": "2018-06-13T15:59:06+00:00" 592 | }, 593 | { 594 | "name": "react/promise-stream", 595 | "version": "v1.1.1", 596 | "source": { 597 | "type": "git", 598 | "url": "https://github.com/reactphp/promise-stream.git", 599 | "reference": "00e269d611e9c9a29356aef64c07f7e513e73dc9" 600 | }, 601 | "dist": { 602 | "type": "zip", 603 | "url": "https://api.github.com/repos/reactphp/promise-stream/zipball/00e269d611e9c9a29356aef64c07f7e513e73dc9", 604 | "reference": "00e269d611e9c9a29356aef64c07f7e513e73dc9", 605 | "shasum": "" 606 | }, 607 | "require": { 608 | "php": ">=5.3", 609 | "react/promise": "^2.1 || ^1.2", 610 | "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4 || ^0.3" 611 | }, 612 | "require-dev": { 613 | "clue/block-react": "^1.0", 614 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35", 615 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3", 616 | "react/promise-timer": "^1.0" 617 | }, 618 | "type": "library", 619 | "autoload": { 620 | "psr-4": { 621 | "React\\Promise\\Stream\\": "src/" 622 | }, 623 | "files": [ 624 | "src/functions_include.php" 625 | ] 626 | }, 627 | "notification-url": "https://packagist.org/downloads/", 628 | "license": [ 629 | "MIT" 630 | ], 631 | "authors": [ 632 | { 633 | "name": "Christian Lück", 634 | "email": "christian@lueck.tv" 635 | } 636 | ], 637 | "description": "The missing link between Promise-land and Stream-land for ReactPHP", 638 | "homepage": "https://github.com/reactphp/promise-stream", 639 | "keywords": [ 640 | "Buffer", 641 | "async", 642 | "promise", 643 | "reactphp", 644 | "stream", 645 | "unwrap" 646 | ], 647 | "time": "2017-12-22T12:02:05+00:00" 648 | }, 649 | { 650 | "name": "react/promise-timer", 651 | "version": "v1.5.0", 652 | "source": { 653 | "type": "git", 654 | "url": "https://github.com/reactphp/promise-timer.git", 655 | "reference": "a11206938ca2394dc7bb368f5da25cd4533fa603" 656 | }, 657 | "dist": { 658 | "type": "zip", 659 | "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/a11206938ca2394dc7bb368f5da25cd4533fa603", 660 | "reference": "a11206938ca2394dc7bb368f5da25cd4533fa603", 661 | "shasum": "" 662 | }, 663 | "require": { 664 | "php": ">=5.3", 665 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5", 666 | "react/promise": "^2.7.0 || ^1.2.1" 667 | }, 668 | "require-dev": { 669 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35" 670 | }, 671 | "type": "library", 672 | "autoload": { 673 | "psr-4": { 674 | "React\\Promise\\Timer\\": "src/" 675 | }, 676 | "files": [ 677 | "src/functions.php" 678 | ] 679 | }, 680 | "notification-url": "https://packagist.org/downloads/", 681 | "license": [ 682 | "MIT" 683 | ], 684 | "authors": [ 685 | { 686 | "name": "Christian Lück", 687 | "email": "christian@lueck.tv" 688 | } 689 | ], 690 | "description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.", 691 | "homepage": "https://github.com/reactphp/promise-timer", 692 | "keywords": [ 693 | "async", 694 | "event-loop", 695 | "promise", 696 | "reactphp", 697 | "timeout", 698 | "timer" 699 | ], 700 | "time": "2018-06-13T16:45:37+00:00" 701 | }, 702 | { 703 | "name": "react/socket", 704 | "version": "v0.8.12", 705 | "source": { 706 | "type": "git", 707 | "url": "https://github.com/reactphp/socket.git", 708 | "reference": "7f7e6c56ccda7418a1a264892a625f38a5bdee0c" 709 | }, 710 | "dist": { 711 | "type": "zip", 712 | "url": "https://api.github.com/repos/reactphp/socket/zipball/7f7e6c56ccda7418a1a264892a625f38a5bdee0c", 713 | "reference": "7f7e6c56ccda7418a1a264892a625f38a5bdee0c", 714 | "shasum": "" 715 | }, 716 | "require": { 717 | "evenement/evenement": "^3.0 || ^2.0 || ^1.0", 718 | "php": ">=5.3.0", 719 | "react/dns": "^0.4.13", 720 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5", 721 | "react/promise": "^2.6.0 || ^1.2.1", 722 | "react/promise-timer": "^1.4.0", 723 | "react/stream": "^1.0 || ^0.7.1" 724 | }, 725 | "require-dev": { 726 | "clue/block-react": "^1.2", 727 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35" 728 | }, 729 | "type": "library", 730 | "autoload": { 731 | "psr-4": { 732 | "React\\Socket\\": "src" 733 | } 734 | }, 735 | "notification-url": "https://packagist.org/downloads/", 736 | "license": [ 737 | "MIT" 738 | ], 739 | "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", 740 | "keywords": [ 741 | "Connection", 742 | "Socket", 743 | "async", 744 | "reactphp", 745 | "stream" 746 | ], 747 | "time": "2018-06-11T14:33:43+00:00" 748 | }, 749 | { 750 | "name": "react/stream", 751 | "version": "v0.7.7", 752 | "source": { 753 | "type": "git", 754 | "url": "https://github.com/reactphp/stream.git", 755 | "reference": "10100896018fd847a257cd81143b8e1b7be08e40" 756 | }, 757 | "dist": { 758 | "type": "zip", 759 | "url": "https://api.github.com/repos/reactphp/stream/zipball/10100896018fd847a257cd81143b8e1b7be08e40", 760 | "reference": "10100896018fd847a257cd81143b8e1b7be08e40", 761 | "shasum": "" 762 | }, 763 | "require": { 764 | "evenement/evenement": "^3.0 || ^2.0 || ^1.0", 765 | "php": ">=5.3.8", 766 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5" 767 | }, 768 | "require-dev": { 769 | "clue/stream-filter": "~1.2", 770 | "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35" 771 | }, 772 | "type": "library", 773 | "autoload": { 774 | "psr-4": { 775 | "React\\Stream\\": "src" 776 | } 777 | }, 778 | "notification-url": "https://packagist.org/downloads/", 779 | "license": [ 780 | "MIT" 781 | ], 782 | "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", 783 | "keywords": [ 784 | "event-driven", 785 | "io", 786 | "non-blocking", 787 | "pipe", 788 | "reactphp", 789 | "readable", 790 | "stream", 791 | "writable" 792 | ], 793 | "time": "2018-01-19T15:04:38+00:00" 794 | }, 795 | { 796 | "name": "ringcentral/psr7", 797 | "version": "1.2.2", 798 | "source": { 799 | "type": "git", 800 | "url": "https://github.com/ringcentral/psr7.git", 801 | "reference": "dcd84bbb49b96c616d1dcc8bfb9bef3f2cd53d1c" 802 | }, 803 | "dist": { 804 | "type": "zip", 805 | "url": "https://api.github.com/repos/ringcentral/psr7/zipball/dcd84bbb49b96c616d1dcc8bfb9bef3f2cd53d1c", 806 | "reference": "dcd84bbb49b96c616d1dcc8bfb9bef3f2cd53d1c", 807 | "shasum": "" 808 | }, 809 | "require": { 810 | "php": ">=5.3", 811 | "psr/http-message": "~1.0" 812 | }, 813 | "provide": { 814 | "psr/http-message-implementation": "1.0" 815 | }, 816 | "require-dev": { 817 | "phpunit/phpunit": "~4.0" 818 | }, 819 | "type": "library", 820 | "extra": { 821 | "branch-alias": { 822 | "dev-master": "1.0-dev" 823 | } 824 | }, 825 | "autoload": { 826 | "psr-4": { 827 | "RingCentral\\Psr7\\": "src/" 828 | }, 829 | "files": [ 830 | "src/functions_include.php" 831 | ] 832 | }, 833 | "notification-url": "https://packagist.org/downloads/", 834 | "license": [ 835 | "MIT" 836 | ], 837 | "authors": [ 838 | { 839 | "name": "Michael Dowling", 840 | "email": "mtdowling@gmail.com", 841 | "homepage": "https://github.com/mtdowling" 842 | } 843 | ], 844 | "description": "PSR-7 message implementation", 845 | "keywords": [ 846 | "http", 847 | "message", 848 | "stream", 849 | "uri" 850 | ], 851 | "time": "2018-01-15T21:00:49+00:00" 852 | } 853 | ], 854 | "packages-dev": [ 855 | { 856 | "name": "amphp/amp", 857 | "version": "v2.0.7", 858 | "source": { 859 | "type": "git", 860 | "url": "https://github.com/amphp/amp.git", 861 | "reference": "d561cc9736bc18dd94a2fc9cdae98b616bd92c43" 862 | }, 863 | "dist": { 864 | "type": "zip", 865 | "url": "https://api.github.com/repos/amphp/amp/zipball/d561cc9736bc18dd94a2fc9cdae98b616bd92c43", 866 | "reference": "d561cc9736bc18dd94a2fc9cdae98b616bd92c43", 867 | "shasum": "" 868 | }, 869 | "require": { 870 | "php": ">=7" 871 | }, 872 | "require-dev": { 873 | "amphp/phpunit-util": "^1", 874 | "friendsofphp/php-cs-fixer": "^2.3", 875 | "phpstan/phpstan": "^0.8.5", 876 | "phpunit/phpunit": "^6.0.9", 877 | "react/promise": "^2" 878 | }, 879 | "type": "library", 880 | "extra": { 881 | "branch-alias": { 882 | "dev-master": "2.0.x-dev" 883 | } 884 | }, 885 | "autoload": { 886 | "psr-4": { 887 | "Amp\\": "lib" 888 | }, 889 | "files": [ 890 | "lib/functions.php", 891 | "lib/Internal/functions.php" 892 | ] 893 | }, 894 | "notification-url": "https://packagist.org/downloads/", 895 | "license": [ 896 | "MIT" 897 | ], 898 | "authors": [ 899 | { 900 | "name": "Bob Weinand", 901 | "email": "bobwei9@hotmail.com" 902 | }, 903 | { 904 | "name": "Niklas Keller", 905 | "email": "me@kelunik.com" 906 | }, 907 | { 908 | "name": "Daniel Lowrey", 909 | "email": "rdlowrey@php.net" 910 | }, 911 | { 912 | "name": "Aaron Piotrowski", 913 | "email": "aaron@trowski.com" 914 | } 915 | ], 916 | "description": "A non-blocking concurrency framework for PHP applications.", 917 | "homepage": "http://amphp.org/amp", 918 | "keywords": [ 919 | "async", 920 | "asynchronous", 921 | "awaitable", 922 | "concurrency", 923 | "event", 924 | "event-loop", 925 | "future", 926 | "non-blocking", 927 | "promise" 928 | ], 929 | "time": "2018-04-30T20:49:57+00:00" 930 | }, 931 | { 932 | "name": "amphp/react-adapter", 933 | "version": "v1.1.0", 934 | "source": { 935 | "type": "git", 936 | "url": "https://github.com/amphp/react-adapter.git", 937 | "reference": "c54710930add61eae97c596e3d2d76830e394ae9" 938 | }, 939 | "dist": { 940 | "type": "zip", 941 | "url": "https://api.github.com/repos/amphp/react-adapter/zipball/c54710930add61eae97c596e3d2d76830e394ae9", 942 | "reference": "c54710930add61eae97c596e3d2d76830e394ae9", 943 | "shasum": "" 944 | }, 945 | "require": { 946 | "amphp/amp": "^2", 947 | "react/event-loop": "^0.4.2" 948 | }, 949 | "require-dev": { 950 | "friendsofphp/php-cs-fixer": "^2.3", 951 | "phpunit/phpunit": "^4.8" 952 | }, 953 | "type": "library", 954 | "autoload": { 955 | "psr-4": { 956 | "Amp\\ReactAdapter\\": "lib" 957 | } 958 | }, 959 | "notification-url": "https://packagist.org/downloads/", 960 | "license": [ 961 | "MIT" 962 | ], 963 | "authors": [ 964 | { 965 | "name": "Niklas Keller", 966 | "email": "me@kelunik.com" 967 | } 968 | ], 969 | "description": "Adapter to make any ReactPHP library compatible with Amp.", 970 | "time": "2017-09-14T15:38:41+00:00" 971 | }, 972 | { 973 | "name": "doctrine/instantiator", 974 | "version": "1.1.0", 975 | "source": { 976 | "type": "git", 977 | "url": "https://github.com/doctrine/instantiator.git", 978 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" 979 | }, 980 | "dist": { 981 | "type": "zip", 982 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", 983 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", 984 | "shasum": "" 985 | }, 986 | "require": { 987 | "php": "^7.1" 988 | }, 989 | "require-dev": { 990 | "athletic/athletic": "~0.1.8", 991 | "ext-pdo": "*", 992 | "ext-phar": "*", 993 | "phpunit/phpunit": "^6.2.3", 994 | "squizlabs/php_codesniffer": "^3.0.2" 995 | }, 996 | "type": "library", 997 | "extra": { 998 | "branch-alias": { 999 | "dev-master": "1.2.x-dev" 1000 | } 1001 | }, 1002 | "autoload": { 1003 | "psr-4": { 1004 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 1005 | } 1006 | }, 1007 | "notification-url": "https://packagist.org/downloads/", 1008 | "license": [ 1009 | "MIT" 1010 | ], 1011 | "authors": [ 1012 | { 1013 | "name": "Marco Pivetta", 1014 | "email": "ocramius@gmail.com", 1015 | "homepage": "http://ocramius.github.com/" 1016 | } 1017 | ], 1018 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 1019 | "homepage": "https://github.com/doctrine/instantiator", 1020 | "keywords": [ 1021 | "constructor", 1022 | "instantiate" 1023 | ], 1024 | "time": "2017-07-22T11:58:36+00:00" 1025 | }, 1026 | { 1027 | "name": "monolog/monolog", 1028 | "version": "1.23.0", 1029 | "source": { 1030 | "type": "git", 1031 | "url": "https://github.com/Seldaek/monolog.git", 1032 | "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" 1033 | }, 1034 | "dist": { 1035 | "type": "zip", 1036 | "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", 1037 | "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", 1038 | "shasum": "" 1039 | }, 1040 | "require": { 1041 | "php": ">=5.3.0", 1042 | "psr/log": "~1.0" 1043 | }, 1044 | "provide": { 1045 | "psr/log-implementation": "1.0.0" 1046 | }, 1047 | "require-dev": { 1048 | "aws/aws-sdk-php": "^2.4.9 || ^3.0", 1049 | "doctrine/couchdb": "~1.0@dev", 1050 | "graylog2/gelf-php": "~1.0", 1051 | "jakub-onderka/php-parallel-lint": "0.9", 1052 | "php-amqplib/php-amqplib": "~2.4", 1053 | "php-console/php-console": "^3.1.3", 1054 | "phpunit/phpunit": "~4.5", 1055 | "phpunit/phpunit-mock-objects": "2.3.0", 1056 | "ruflin/elastica": ">=0.90 <3.0", 1057 | "sentry/sentry": "^0.13", 1058 | "swiftmailer/swiftmailer": "^5.3|^6.0" 1059 | }, 1060 | "suggest": { 1061 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", 1062 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server", 1063 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", 1064 | "ext-mongo": "Allow sending log messages to a MongoDB server", 1065 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", 1066 | "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", 1067 | "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", 1068 | "php-console/php-console": "Allow sending log messages to Google Chrome", 1069 | "rollbar/rollbar": "Allow sending log messages to Rollbar", 1070 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server", 1071 | "sentry/sentry": "Allow sending log messages to a Sentry server" 1072 | }, 1073 | "type": "library", 1074 | "extra": { 1075 | "branch-alias": { 1076 | "dev-master": "2.0.x-dev" 1077 | } 1078 | }, 1079 | "autoload": { 1080 | "psr-4": { 1081 | "Monolog\\": "src/Monolog" 1082 | } 1083 | }, 1084 | "notification-url": "https://packagist.org/downloads/", 1085 | "license": [ 1086 | "MIT" 1087 | ], 1088 | "authors": [ 1089 | { 1090 | "name": "Jordi Boggiano", 1091 | "email": "j.boggiano@seld.be", 1092 | "homepage": "http://seld.be" 1093 | } 1094 | ], 1095 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services", 1096 | "homepage": "http://github.com/Seldaek/monolog", 1097 | "keywords": [ 1098 | "log", 1099 | "logging", 1100 | "psr-3" 1101 | ], 1102 | "time": "2017-06-19T01:22:40+00:00" 1103 | }, 1104 | { 1105 | "name": "myclabs/deep-copy", 1106 | "version": "1.8.1", 1107 | "source": { 1108 | "type": "git", 1109 | "url": "https://github.com/myclabs/DeepCopy.git", 1110 | "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" 1111 | }, 1112 | "dist": { 1113 | "type": "zip", 1114 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", 1115 | "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", 1116 | "shasum": "" 1117 | }, 1118 | "require": { 1119 | "php": "^7.1" 1120 | }, 1121 | "replace": { 1122 | "myclabs/deep-copy": "self.version" 1123 | }, 1124 | "require-dev": { 1125 | "doctrine/collections": "^1.0", 1126 | "doctrine/common": "^2.6", 1127 | "phpunit/phpunit": "^7.1" 1128 | }, 1129 | "type": "library", 1130 | "autoload": { 1131 | "psr-4": { 1132 | "DeepCopy\\": "src/DeepCopy/" 1133 | }, 1134 | "files": [ 1135 | "src/DeepCopy/deep_copy.php" 1136 | ] 1137 | }, 1138 | "notification-url": "https://packagist.org/downloads/", 1139 | "license": [ 1140 | "MIT" 1141 | ], 1142 | "description": "Create deep copies (clones) of your objects", 1143 | "keywords": [ 1144 | "clone", 1145 | "copy", 1146 | "duplicate", 1147 | "object", 1148 | "object graph" 1149 | ], 1150 | "time": "2018-06-11T23:09:50+00:00" 1151 | }, 1152 | { 1153 | "name": "phar-io/manifest", 1154 | "version": "1.0.1", 1155 | "source": { 1156 | "type": "git", 1157 | "url": "https://github.com/phar-io/manifest.git", 1158 | "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" 1159 | }, 1160 | "dist": { 1161 | "type": "zip", 1162 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", 1163 | "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", 1164 | "shasum": "" 1165 | }, 1166 | "require": { 1167 | "ext-dom": "*", 1168 | "ext-phar": "*", 1169 | "phar-io/version": "^1.0.1", 1170 | "php": "^5.6 || ^7.0" 1171 | }, 1172 | "type": "library", 1173 | "extra": { 1174 | "branch-alias": { 1175 | "dev-master": "1.0.x-dev" 1176 | } 1177 | }, 1178 | "autoload": { 1179 | "classmap": [ 1180 | "src/" 1181 | ] 1182 | }, 1183 | "notification-url": "https://packagist.org/downloads/", 1184 | "license": [ 1185 | "BSD-3-Clause" 1186 | ], 1187 | "authors": [ 1188 | { 1189 | "name": "Arne Blankerts", 1190 | "email": "arne@blankerts.de", 1191 | "role": "Developer" 1192 | }, 1193 | { 1194 | "name": "Sebastian Heuer", 1195 | "email": "sebastian@phpeople.de", 1196 | "role": "Developer" 1197 | }, 1198 | { 1199 | "name": "Sebastian Bergmann", 1200 | "email": "sebastian@phpunit.de", 1201 | "role": "Developer" 1202 | } 1203 | ], 1204 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 1205 | "time": "2017-03-05T18:14:27+00:00" 1206 | }, 1207 | { 1208 | "name": "phar-io/version", 1209 | "version": "1.0.1", 1210 | "source": { 1211 | "type": "git", 1212 | "url": "https://github.com/phar-io/version.git", 1213 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" 1214 | }, 1215 | "dist": { 1216 | "type": "zip", 1217 | "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", 1218 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", 1219 | "shasum": "" 1220 | }, 1221 | "require": { 1222 | "php": "^5.6 || ^7.0" 1223 | }, 1224 | "type": "library", 1225 | "autoload": { 1226 | "classmap": [ 1227 | "src/" 1228 | ] 1229 | }, 1230 | "notification-url": "https://packagist.org/downloads/", 1231 | "license": [ 1232 | "BSD-3-Clause" 1233 | ], 1234 | "authors": [ 1235 | { 1236 | "name": "Arne Blankerts", 1237 | "email": "arne@blankerts.de", 1238 | "role": "Developer" 1239 | }, 1240 | { 1241 | "name": "Sebastian Heuer", 1242 | "email": "sebastian@phpeople.de", 1243 | "role": "Developer" 1244 | }, 1245 | { 1246 | "name": "Sebastian Bergmann", 1247 | "email": "sebastian@phpunit.de", 1248 | "role": "Developer" 1249 | } 1250 | ], 1251 | "description": "Library for handling version information and constraints", 1252 | "time": "2017-03-05T17:38:23+00:00" 1253 | }, 1254 | { 1255 | "name": "phpdocumentor/reflection-common", 1256 | "version": "1.0.1", 1257 | "source": { 1258 | "type": "git", 1259 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 1260 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" 1261 | }, 1262 | "dist": { 1263 | "type": "zip", 1264 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 1265 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 1266 | "shasum": "" 1267 | }, 1268 | "require": { 1269 | "php": ">=5.5" 1270 | }, 1271 | "require-dev": { 1272 | "phpunit/phpunit": "^4.6" 1273 | }, 1274 | "type": "library", 1275 | "extra": { 1276 | "branch-alias": { 1277 | "dev-master": "1.0.x-dev" 1278 | } 1279 | }, 1280 | "autoload": { 1281 | "psr-4": { 1282 | "phpDocumentor\\Reflection\\": [ 1283 | "src" 1284 | ] 1285 | } 1286 | }, 1287 | "notification-url": "https://packagist.org/downloads/", 1288 | "license": [ 1289 | "MIT" 1290 | ], 1291 | "authors": [ 1292 | { 1293 | "name": "Jaap van Otterdijk", 1294 | "email": "opensource@ijaap.nl" 1295 | } 1296 | ], 1297 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 1298 | "homepage": "http://www.phpdoc.org", 1299 | "keywords": [ 1300 | "FQSEN", 1301 | "phpDocumentor", 1302 | "phpdoc", 1303 | "reflection", 1304 | "static analysis" 1305 | ], 1306 | "time": "2017-09-11T18:02:19+00:00" 1307 | }, 1308 | { 1309 | "name": "phpdocumentor/reflection-docblock", 1310 | "version": "4.3.0", 1311 | "source": { 1312 | "type": "git", 1313 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 1314 | "reference": "94fd0001232e47129dd3504189fa1c7225010d08" 1315 | }, 1316 | "dist": { 1317 | "type": "zip", 1318 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", 1319 | "reference": "94fd0001232e47129dd3504189fa1c7225010d08", 1320 | "shasum": "" 1321 | }, 1322 | "require": { 1323 | "php": "^7.0", 1324 | "phpdocumentor/reflection-common": "^1.0.0", 1325 | "phpdocumentor/type-resolver": "^0.4.0", 1326 | "webmozart/assert": "^1.0" 1327 | }, 1328 | "require-dev": { 1329 | "doctrine/instantiator": "~1.0.5", 1330 | "mockery/mockery": "^1.0", 1331 | "phpunit/phpunit": "^6.4" 1332 | }, 1333 | "type": "library", 1334 | "extra": { 1335 | "branch-alias": { 1336 | "dev-master": "4.x-dev" 1337 | } 1338 | }, 1339 | "autoload": { 1340 | "psr-4": { 1341 | "phpDocumentor\\Reflection\\": [ 1342 | "src/" 1343 | ] 1344 | } 1345 | }, 1346 | "notification-url": "https://packagist.org/downloads/", 1347 | "license": [ 1348 | "MIT" 1349 | ], 1350 | "authors": [ 1351 | { 1352 | "name": "Mike van Riel", 1353 | "email": "me@mikevanriel.com" 1354 | } 1355 | ], 1356 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 1357 | "time": "2017-11-30T07:14:17+00:00" 1358 | }, 1359 | { 1360 | "name": "phpdocumentor/type-resolver", 1361 | "version": "0.4.0", 1362 | "source": { 1363 | "type": "git", 1364 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 1365 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" 1366 | }, 1367 | "dist": { 1368 | "type": "zip", 1369 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", 1370 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", 1371 | "shasum": "" 1372 | }, 1373 | "require": { 1374 | "php": "^5.5 || ^7.0", 1375 | "phpdocumentor/reflection-common": "^1.0" 1376 | }, 1377 | "require-dev": { 1378 | "mockery/mockery": "^0.9.4", 1379 | "phpunit/phpunit": "^5.2||^4.8.24" 1380 | }, 1381 | "type": "library", 1382 | "extra": { 1383 | "branch-alias": { 1384 | "dev-master": "1.0.x-dev" 1385 | } 1386 | }, 1387 | "autoload": { 1388 | "psr-4": { 1389 | "phpDocumentor\\Reflection\\": [ 1390 | "src/" 1391 | ] 1392 | } 1393 | }, 1394 | "notification-url": "https://packagist.org/downloads/", 1395 | "license": [ 1396 | "MIT" 1397 | ], 1398 | "authors": [ 1399 | { 1400 | "name": "Mike van Riel", 1401 | "email": "me@mikevanriel.com" 1402 | } 1403 | ], 1404 | "time": "2017-07-14T14:27:02+00:00" 1405 | }, 1406 | { 1407 | "name": "phpspec/prophecy", 1408 | "version": "1.7.6", 1409 | "source": { 1410 | "type": "git", 1411 | "url": "https://github.com/phpspec/prophecy.git", 1412 | "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" 1413 | }, 1414 | "dist": { 1415 | "type": "zip", 1416 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", 1417 | "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", 1418 | "shasum": "" 1419 | }, 1420 | "require": { 1421 | "doctrine/instantiator": "^1.0.2", 1422 | "php": "^5.3|^7.0", 1423 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", 1424 | "sebastian/comparator": "^1.1|^2.0|^3.0", 1425 | "sebastian/recursion-context": "^1.0|^2.0|^3.0" 1426 | }, 1427 | "require-dev": { 1428 | "phpspec/phpspec": "^2.5|^3.2", 1429 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" 1430 | }, 1431 | "type": "library", 1432 | "extra": { 1433 | "branch-alias": { 1434 | "dev-master": "1.7.x-dev" 1435 | } 1436 | }, 1437 | "autoload": { 1438 | "psr-0": { 1439 | "Prophecy\\": "src/" 1440 | } 1441 | }, 1442 | "notification-url": "https://packagist.org/downloads/", 1443 | "license": [ 1444 | "MIT" 1445 | ], 1446 | "authors": [ 1447 | { 1448 | "name": "Konstantin Kudryashov", 1449 | "email": "ever.zet@gmail.com", 1450 | "homepage": "http://everzet.com" 1451 | }, 1452 | { 1453 | "name": "Marcello Duarte", 1454 | "email": "marcello.duarte@gmail.com" 1455 | } 1456 | ], 1457 | "description": "Highly opinionated mocking framework for PHP 5.3+", 1458 | "homepage": "https://github.com/phpspec/prophecy", 1459 | "keywords": [ 1460 | "Double", 1461 | "Dummy", 1462 | "fake", 1463 | "mock", 1464 | "spy", 1465 | "stub" 1466 | ], 1467 | "time": "2018-04-18T13:57:24+00:00" 1468 | }, 1469 | { 1470 | "name": "phpunit/php-code-coverage", 1471 | "version": "5.3.2", 1472 | "source": { 1473 | "type": "git", 1474 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 1475 | "reference": "c89677919c5dd6d3b3852f230a663118762218ac" 1476 | }, 1477 | "dist": { 1478 | "type": "zip", 1479 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", 1480 | "reference": "c89677919c5dd6d3b3852f230a663118762218ac", 1481 | "shasum": "" 1482 | }, 1483 | "require": { 1484 | "ext-dom": "*", 1485 | "ext-xmlwriter": "*", 1486 | "php": "^7.0", 1487 | "phpunit/php-file-iterator": "^1.4.2", 1488 | "phpunit/php-text-template": "^1.2.1", 1489 | "phpunit/php-token-stream": "^2.0.1", 1490 | "sebastian/code-unit-reverse-lookup": "^1.0.1", 1491 | "sebastian/environment": "^3.0", 1492 | "sebastian/version": "^2.0.1", 1493 | "theseer/tokenizer": "^1.1" 1494 | }, 1495 | "require-dev": { 1496 | "phpunit/phpunit": "^6.0" 1497 | }, 1498 | "suggest": { 1499 | "ext-xdebug": "^2.5.5" 1500 | }, 1501 | "type": "library", 1502 | "extra": { 1503 | "branch-alias": { 1504 | "dev-master": "5.3.x-dev" 1505 | } 1506 | }, 1507 | "autoload": { 1508 | "classmap": [ 1509 | "src/" 1510 | ] 1511 | }, 1512 | "notification-url": "https://packagist.org/downloads/", 1513 | "license": [ 1514 | "BSD-3-Clause" 1515 | ], 1516 | "authors": [ 1517 | { 1518 | "name": "Sebastian Bergmann", 1519 | "email": "sebastian@phpunit.de", 1520 | "role": "lead" 1521 | } 1522 | ], 1523 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 1524 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 1525 | "keywords": [ 1526 | "coverage", 1527 | "testing", 1528 | "xunit" 1529 | ], 1530 | "time": "2018-04-06T15:36:58+00:00" 1531 | }, 1532 | { 1533 | "name": "phpunit/php-file-iterator", 1534 | "version": "1.4.5", 1535 | "source": { 1536 | "type": "git", 1537 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 1538 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" 1539 | }, 1540 | "dist": { 1541 | "type": "zip", 1542 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", 1543 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", 1544 | "shasum": "" 1545 | }, 1546 | "require": { 1547 | "php": ">=5.3.3" 1548 | }, 1549 | "type": "library", 1550 | "extra": { 1551 | "branch-alias": { 1552 | "dev-master": "1.4.x-dev" 1553 | } 1554 | }, 1555 | "autoload": { 1556 | "classmap": [ 1557 | "src/" 1558 | ] 1559 | }, 1560 | "notification-url": "https://packagist.org/downloads/", 1561 | "license": [ 1562 | "BSD-3-Clause" 1563 | ], 1564 | "authors": [ 1565 | { 1566 | "name": "Sebastian Bergmann", 1567 | "email": "sb@sebastian-bergmann.de", 1568 | "role": "lead" 1569 | } 1570 | ], 1571 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 1572 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 1573 | "keywords": [ 1574 | "filesystem", 1575 | "iterator" 1576 | ], 1577 | "time": "2017-11-27T13:52:08+00:00" 1578 | }, 1579 | { 1580 | "name": "phpunit/php-text-template", 1581 | "version": "1.2.1", 1582 | "source": { 1583 | "type": "git", 1584 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 1585 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 1586 | }, 1587 | "dist": { 1588 | "type": "zip", 1589 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1590 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1591 | "shasum": "" 1592 | }, 1593 | "require": { 1594 | "php": ">=5.3.3" 1595 | }, 1596 | "type": "library", 1597 | "autoload": { 1598 | "classmap": [ 1599 | "src/" 1600 | ] 1601 | }, 1602 | "notification-url": "https://packagist.org/downloads/", 1603 | "license": [ 1604 | "BSD-3-Clause" 1605 | ], 1606 | "authors": [ 1607 | { 1608 | "name": "Sebastian Bergmann", 1609 | "email": "sebastian@phpunit.de", 1610 | "role": "lead" 1611 | } 1612 | ], 1613 | "description": "Simple template engine.", 1614 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 1615 | "keywords": [ 1616 | "template" 1617 | ], 1618 | "time": "2015-06-21T13:50:34+00:00" 1619 | }, 1620 | { 1621 | "name": "phpunit/php-timer", 1622 | "version": "1.0.9", 1623 | "source": { 1624 | "type": "git", 1625 | "url": "https://github.com/sebastianbergmann/php-timer.git", 1626 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" 1627 | }, 1628 | "dist": { 1629 | "type": "zip", 1630 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 1631 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 1632 | "shasum": "" 1633 | }, 1634 | "require": { 1635 | "php": "^5.3.3 || ^7.0" 1636 | }, 1637 | "require-dev": { 1638 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 1639 | }, 1640 | "type": "library", 1641 | "extra": { 1642 | "branch-alias": { 1643 | "dev-master": "1.0-dev" 1644 | } 1645 | }, 1646 | "autoload": { 1647 | "classmap": [ 1648 | "src/" 1649 | ] 1650 | }, 1651 | "notification-url": "https://packagist.org/downloads/", 1652 | "license": [ 1653 | "BSD-3-Clause" 1654 | ], 1655 | "authors": [ 1656 | { 1657 | "name": "Sebastian Bergmann", 1658 | "email": "sb@sebastian-bergmann.de", 1659 | "role": "lead" 1660 | } 1661 | ], 1662 | "description": "Utility class for timing", 1663 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 1664 | "keywords": [ 1665 | "timer" 1666 | ], 1667 | "time": "2017-02-26T11:10:40+00:00" 1668 | }, 1669 | { 1670 | "name": "phpunit/php-token-stream", 1671 | "version": "2.0.2", 1672 | "source": { 1673 | "type": "git", 1674 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 1675 | "reference": "791198a2c6254db10131eecfe8c06670700904db" 1676 | }, 1677 | "dist": { 1678 | "type": "zip", 1679 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", 1680 | "reference": "791198a2c6254db10131eecfe8c06670700904db", 1681 | "shasum": "" 1682 | }, 1683 | "require": { 1684 | "ext-tokenizer": "*", 1685 | "php": "^7.0" 1686 | }, 1687 | "require-dev": { 1688 | "phpunit/phpunit": "^6.2.4" 1689 | }, 1690 | "type": "library", 1691 | "extra": { 1692 | "branch-alias": { 1693 | "dev-master": "2.0-dev" 1694 | } 1695 | }, 1696 | "autoload": { 1697 | "classmap": [ 1698 | "src/" 1699 | ] 1700 | }, 1701 | "notification-url": "https://packagist.org/downloads/", 1702 | "license": [ 1703 | "BSD-3-Clause" 1704 | ], 1705 | "authors": [ 1706 | { 1707 | "name": "Sebastian Bergmann", 1708 | "email": "sebastian@phpunit.de" 1709 | } 1710 | ], 1711 | "description": "Wrapper around PHP's tokenizer extension.", 1712 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 1713 | "keywords": [ 1714 | "tokenizer" 1715 | ], 1716 | "time": "2017-11-27T05:48:46+00:00" 1717 | }, 1718 | { 1719 | "name": "phpunit/phpunit", 1720 | "version": "6.5.9", 1721 | "source": { 1722 | "type": "git", 1723 | "url": "https://github.com/sebastianbergmann/phpunit.git", 1724 | "reference": "093ca5508174cd8ab8efe44fd1dde447adfdec8f" 1725 | }, 1726 | "dist": { 1727 | "type": "zip", 1728 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/093ca5508174cd8ab8efe44fd1dde447adfdec8f", 1729 | "reference": "093ca5508174cd8ab8efe44fd1dde447adfdec8f", 1730 | "shasum": "" 1731 | }, 1732 | "require": { 1733 | "ext-dom": "*", 1734 | "ext-json": "*", 1735 | "ext-libxml": "*", 1736 | "ext-mbstring": "*", 1737 | "ext-xml": "*", 1738 | "myclabs/deep-copy": "^1.6.1", 1739 | "phar-io/manifest": "^1.0.1", 1740 | "phar-io/version": "^1.0", 1741 | "php": "^7.0", 1742 | "phpspec/prophecy": "^1.7", 1743 | "phpunit/php-code-coverage": "^5.3", 1744 | "phpunit/php-file-iterator": "^1.4.3", 1745 | "phpunit/php-text-template": "^1.2.1", 1746 | "phpunit/php-timer": "^1.0.9", 1747 | "phpunit/phpunit-mock-objects": "^5.0.5", 1748 | "sebastian/comparator": "^2.1", 1749 | "sebastian/diff": "^2.0", 1750 | "sebastian/environment": "^3.1", 1751 | "sebastian/exporter": "^3.1", 1752 | "sebastian/global-state": "^2.0", 1753 | "sebastian/object-enumerator": "^3.0.3", 1754 | "sebastian/resource-operations": "^1.0", 1755 | "sebastian/version": "^2.0.1" 1756 | }, 1757 | "conflict": { 1758 | "phpdocumentor/reflection-docblock": "3.0.2", 1759 | "phpunit/dbunit": "<3.0" 1760 | }, 1761 | "require-dev": { 1762 | "ext-pdo": "*" 1763 | }, 1764 | "suggest": { 1765 | "ext-xdebug": "*", 1766 | "phpunit/php-invoker": "^1.1" 1767 | }, 1768 | "bin": [ 1769 | "phpunit" 1770 | ], 1771 | "type": "library", 1772 | "extra": { 1773 | "branch-alias": { 1774 | "dev-master": "6.5.x-dev" 1775 | } 1776 | }, 1777 | "autoload": { 1778 | "classmap": [ 1779 | "src/" 1780 | ] 1781 | }, 1782 | "notification-url": "https://packagist.org/downloads/", 1783 | "license": [ 1784 | "BSD-3-Clause" 1785 | ], 1786 | "authors": [ 1787 | { 1788 | "name": "Sebastian Bergmann", 1789 | "email": "sebastian@phpunit.de", 1790 | "role": "lead" 1791 | } 1792 | ], 1793 | "description": "The PHP Unit Testing framework.", 1794 | "homepage": "https://phpunit.de/", 1795 | "keywords": [ 1796 | "phpunit", 1797 | "testing", 1798 | "xunit" 1799 | ], 1800 | "time": "2018-07-03T06:40:40+00:00" 1801 | }, 1802 | { 1803 | "name": "phpunit/phpunit-mock-objects", 1804 | "version": "5.0.7", 1805 | "source": { 1806 | "type": "git", 1807 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 1808 | "reference": "3eaf040f20154d27d6da59ca2c6e28ac8fd56dce" 1809 | }, 1810 | "dist": { 1811 | "type": "zip", 1812 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3eaf040f20154d27d6da59ca2c6e28ac8fd56dce", 1813 | "reference": "3eaf040f20154d27d6da59ca2c6e28ac8fd56dce", 1814 | "shasum": "" 1815 | }, 1816 | "require": { 1817 | "doctrine/instantiator": "^1.0.5", 1818 | "php": "^7.0", 1819 | "phpunit/php-text-template": "^1.2.1", 1820 | "sebastian/exporter": "^3.1" 1821 | }, 1822 | "conflict": { 1823 | "phpunit/phpunit": "<6.0" 1824 | }, 1825 | "require-dev": { 1826 | "phpunit/phpunit": "^6.5" 1827 | }, 1828 | "suggest": { 1829 | "ext-soap": "*" 1830 | }, 1831 | "type": "library", 1832 | "extra": { 1833 | "branch-alias": { 1834 | "dev-master": "5.0.x-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 | "role": "lead" 1851 | } 1852 | ], 1853 | "description": "Mock Object library for PHPUnit", 1854 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1855 | "keywords": [ 1856 | "mock", 1857 | "xunit" 1858 | ], 1859 | "time": "2018-05-29T13:50:43+00:00" 1860 | }, 1861 | { 1862 | "name": "psr/log", 1863 | "version": "1.0.2", 1864 | "source": { 1865 | "type": "git", 1866 | "url": "https://github.com/php-fig/log.git", 1867 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" 1868 | }, 1869 | "dist": { 1870 | "type": "zip", 1871 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 1872 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 1873 | "shasum": "" 1874 | }, 1875 | "require": { 1876 | "php": ">=5.3.0" 1877 | }, 1878 | "type": "library", 1879 | "extra": { 1880 | "branch-alias": { 1881 | "dev-master": "1.0.x-dev" 1882 | } 1883 | }, 1884 | "autoload": { 1885 | "psr-4": { 1886 | "Psr\\Log\\": "Psr/Log/" 1887 | } 1888 | }, 1889 | "notification-url": "https://packagist.org/downloads/", 1890 | "license": [ 1891 | "MIT" 1892 | ], 1893 | "authors": [ 1894 | { 1895 | "name": "PHP-FIG", 1896 | "homepage": "http://www.php-fig.org/" 1897 | } 1898 | ], 1899 | "description": "Common interface for logging libraries", 1900 | "homepage": "https://github.com/php-fig/log", 1901 | "keywords": [ 1902 | "log", 1903 | "psr", 1904 | "psr-3" 1905 | ], 1906 | "time": "2016-10-10T12:19:37+00:00" 1907 | }, 1908 | { 1909 | "name": "sebastian/code-unit-reverse-lookup", 1910 | "version": "1.0.1", 1911 | "source": { 1912 | "type": "git", 1913 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 1914 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" 1915 | }, 1916 | "dist": { 1917 | "type": "zip", 1918 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 1919 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 1920 | "shasum": "" 1921 | }, 1922 | "require": { 1923 | "php": "^5.6 || ^7.0" 1924 | }, 1925 | "require-dev": { 1926 | "phpunit/phpunit": "^5.7 || ^6.0" 1927 | }, 1928 | "type": "library", 1929 | "extra": { 1930 | "branch-alias": { 1931 | "dev-master": "1.0.x-dev" 1932 | } 1933 | }, 1934 | "autoload": { 1935 | "classmap": [ 1936 | "src/" 1937 | ] 1938 | }, 1939 | "notification-url": "https://packagist.org/downloads/", 1940 | "license": [ 1941 | "BSD-3-Clause" 1942 | ], 1943 | "authors": [ 1944 | { 1945 | "name": "Sebastian Bergmann", 1946 | "email": "sebastian@phpunit.de" 1947 | } 1948 | ], 1949 | "description": "Looks up which function or method a line of code belongs to", 1950 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 1951 | "time": "2017-03-04T06:30:41+00:00" 1952 | }, 1953 | { 1954 | "name": "sebastian/comparator", 1955 | "version": "2.1.3", 1956 | "source": { 1957 | "type": "git", 1958 | "url": "https://github.com/sebastianbergmann/comparator.git", 1959 | "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" 1960 | }, 1961 | "dist": { 1962 | "type": "zip", 1963 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", 1964 | "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", 1965 | "shasum": "" 1966 | }, 1967 | "require": { 1968 | "php": "^7.0", 1969 | "sebastian/diff": "^2.0 || ^3.0", 1970 | "sebastian/exporter": "^3.1" 1971 | }, 1972 | "require-dev": { 1973 | "phpunit/phpunit": "^6.4" 1974 | }, 1975 | "type": "library", 1976 | "extra": { 1977 | "branch-alias": { 1978 | "dev-master": "2.1.x-dev" 1979 | } 1980 | }, 1981 | "autoload": { 1982 | "classmap": [ 1983 | "src/" 1984 | ] 1985 | }, 1986 | "notification-url": "https://packagist.org/downloads/", 1987 | "license": [ 1988 | "BSD-3-Clause" 1989 | ], 1990 | "authors": [ 1991 | { 1992 | "name": "Jeff Welch", 1993 | "email": "whatthejeff@gmail.com" 1994 | }, 1995 | { 1996 | "name": "Volker Dusch", 1997 | "email": "github@wallbash.com" 1998 | }, 1999 | { 2000 | "name": "Bernhard Schussek", 2001 | "email": "bschussek@2bepublished.at" 2002 | }, 2003 | { 2004 | "name": "Sebastian Bergmann", 2005 | "email": "sebastian@phpunit.de" 2006 | } 2007 | ], 2008 | "description": "Provides the functionality to compare PHP values for equality", 2009 | "homepage": "https://github.com/sebastianbergmann/comparator", 2010 | "keywords": [ 2011 | "comparator", 2012 | "compare", 2013 | "equality" 2014 | ], 2015 | "time": "2018-02-01T13:46:46+00:00" 2016 | }, 2017 | { 2018 | "name": "sebastian/diff", 2019 | "version": "2.0.1", 2020 | "source": { 2021 | "type": "git", 2022 | "url": "https://github.com/sebastianbergmann/diff.git", 2023 | "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" 2024 | }, 2025 | "dist": { 2026 | "type": "zip", 2027 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", 2028 | "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", 2029 | "shasum": "" 2030 | }, 2031 | "require": { 2032 | "php": "^7.0" 2033 | }, 2034 | "require-dev": { 2035 | "phpunit/phpunit": "^6.2" 2036 | }, 2037 | "type": "library", 2038 | "extra": { 2039 | "branch-alias": { 2040 | "dev-master": "2.0-dev" 2041 | } 2042 | }, 2043 | "autoload": { 2044 | "classmap": [ 2045 | "src/" 2046 | ] 2047 | }, 2048 | "notification-url": "https://packagist.org/downloads/", 2049 | "license": [ 2050 | "BSD-3-Clause" 2051 | ], 2052 | "authors": [ 2053 | { 2054 | "name": "Kore Nordmann", 2055 | "email": "mail@kore-nordmann.de" 2056 | }, 2057 | { 2058 | "name": "Sebastian Bergmann", 2059 | "email": "sebastian@phpunit.de" 2060 | } 2061 | ], 2062 | "description": "Diff implementation", 2063 | "homepage": "https://github.com/sebastianbergmann/diff", 2064 | "keywords": [ 2065 | "diff" 2066 | ], 2067 | "time": "2017-08-03T08:09:46+00:00" 2068 | }, 2069 | { 2070 | "name": "sebastian/environment", 2071 | "version": "3.1.0", 2072 | "source": { 2073 | "type": "git", 2074 | "url": "https://github.com/sebastianbergmann/environment.git", 2075 | "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" 2076 | }, 2077 | "dist": { 2078 | "type": "zip", 2079 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", 2080 | "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", 2081 | "shasum": "" 2082 | }, 2083 | "require": { 2084 | "php": "^7.0" 2085 | }, 2086 | "require-dev": { 2087 | "phpunit/phpunit": "^6.1" 2088 | }, 2089 | "type": "library", 2090 | "extra": { 2091 | "branch-alias": { 2092 | "dev-master": "3.1.x-dev" 2093 | } 2094 | }, 2095 | "autoload": { 2096 | "classmap": [ 2097 | "src/" 2098 | ] 2099 | }, 2100 | "notification-url": "https://packagist.org/downloads/", 2101 | "license": [ 2102 | "BSD-3-Clause" 2103 | ], 2104 | "authors": [ 2105 | { 2106 | "name": "Sebastian Bergmann", 2107 | "email": "sebastian@phpunit.de" 2108 | } 2109 | ], 2110 | "description": "Provides functionality to handle HHVM/PHP environments", 2111 | "homepage": "http://www.github.com/sebastianbergmann/environment", 2112 | "keywords": [ 2113 | "Xdebug", 2114 | "environment", 2115 | "hhvm" 2116 | ], 2117 | "time": "2017-07-01T08:51:00+00:00" 2118 | }, 2119 | { 2120 | "name": "sebastian/exporter", 2121 | "version": "3.1.0", 2122 | "source": { 2123 | "type": "git", 2124 | "url": "https://github.com/sebastianbergmann/exporter.git", 2125 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" 2126 | }, 2127 | "dist": { 2128 | "type": "zip", 2129 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", 2130 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", 2131 | "shasum": "" 2132 | }, 2133 | "require": { 2134 | "php": "^7.0", 2135 | "sebastian/recursion-context": "^3.0" 2136 | }, 2137 | "require-dev": { 2138 | "ext-mbstring": "*", 2139 | "phpunit/phpunit": "^6.0" 2140 | }, 2141 | "type": "library", 2142 | "extra": { 2143 | "branch-alias": { 2144 | "dev-master": "3.1.x-dev" 2145 | } 2146 | }, 2147 | "autoload": { 2148 | "classmap": [ 2149 | "src/" 2150 | ] 2151 | }, 2152 | "notification-url": "https://packagist.org/downloads/", 2153 | "license": [ 2154 | "BSD-3-Clause" 2155 | ], 2156 | "authors": [ 2157 | { 2158 | "name": "Jeff Welch", 2159 | "email": "whatthejeff@gmail.com" 2160 | }, 2161 | { 2162 | "name": "Volker Dusch", 2163 | "email": "github@wallbash.com" 2164 | }, 2165 | { 2166 | "name": "Bernhard Schussek", 2167 | "email": "bschussek@2bepublished.at" 2168 | }, 2169 | { 2170 | "name": "Sebastian Bergmann", 2171 | "email": "sebastian@phpunit.de" 2172 | }, 2173 | { 2174 | "name": "Adam Harvey", 2175 | "email": "aharvey@php.net" 2176 | } 2177 | ], 2178 | "description": "Provides the functionality to export PHP variables for visualization", 2179 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 2180 | "keywords": [ 2181 | "export", 2182 | "exporter" 2183 | ], 2184 | "time": "2017-04-03T13:19:02+00:00" 2185 | }, 2186 | { 2187 | "name": "sebastian/global-state", 2188 | "version": "2.0.0", 2189 | "source": { 2190 | "type": "git", 2191 | "url": "https://github.com/sebastianbergmann/global-state.git", 2192 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" 2193 | }, 2194 | "dist": { 2195 | "type": "zip", 2196 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", 2197 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", 2198 | "shasum": "" 2199 | }, 2200 | "require": { 2201 | "php": "^7.0" 2202 | }, 2203 | "require-dev": { 2204 | "phpunit/phpunit": "^6.0" 2205 | }, 2206 | "suggest": { 2207 | "ext-uopz": "*" 2208 | }, 2209 | "type": "library", 2210 | "extra": { 2211 | "branch-alias": { 2212 | "dev-master": "2.0-dev" 2213 | } 2214 | }, 2215 | "autoload": { 2216 | "classmap": [ 2217 | "src/" 2218 | ] 2219 | }, 2220 | "notification-url": "https://packagist.org/downloads/", 2221 | "license": [ 2222 | "BSD-3-Clause" 2223 | ], 2224 | "authors": [ 2225 | { 2226 | "name": "Sebastian Bergmann", 2227 | "email": "sebastian@phpunit.de" 2228 | } 2229 | ], 2230 | "description": "Snapshotting of global state", 2231 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 2232 | "keywords": [ 2233 | "global state" 2234 | ], 2235 | "time": "2017-04-27T15:39:26+00:00" 2236 | }, 2237 | { 2238 | "name": "sebastian/object-enumerator", 2239 | "version": "3.0.3", 2240 | "source": { 2241 | "type": "git", 2242 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 2243 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" 2244 | }, 2245 | "dist": { 2246 | "type": "zip", 2247 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", 2248 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", 2249 | "shasum": "" 2250 | }, 2251 | "require": { 2252 | "php": "^7.0", 2253 | "sebastian/object-reflector": "^1.1.1", 2254 | "sebastian/recursion-context": "^3.0" 2255 | }, 2256 | "require-dev": { 2257 | "phpunit/phpunit": "^6.0" 2258 | }, 2259 | "type": "library", 2260 | "extra": { 2261 | "branch-alias": { 2262 | "dev-master": "3.0.x-dev" 2263 | } 2264 | }, 2265 | "autoload": { 2266 | "classmap": [ 2267 | "src/" 2268 | ] 2269 | }, 2270 | "notification-url": "https://packagist.org/downloads/", 2271 | "license": [ 2272 | "BSD-3-Clause" 2273 | ], 2274 | "authors": [ 2275 | { 2276 | "name": "Sebastian Bergmann", 2277 | "email": "sebastian@phpunit.de" 2278 | } 2279 | ], 2280 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 2281 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 2282 | "time": "2017-08-03T12:35:26+00:00" 2283 | }, 2284 | { 2285 | "name": "sebastian/object-reflector", 2286 | "version": "1.1.1", 2287 | "source": { 2288 | "type": "git", 2289 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 2290 | "reference": "773f97c67f28de00d397be301821b06708fca0be" 2291 | }, 2292 | "dist": { 2293 | "type": "zip", 2294 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", 2295 | "reference": "773f97c67f28de00d397be301821b06708fca0be", 2296 | "shasum": "" 2297 | }, 2298 | "require": { 2299 | "php": "^7.0" 2300 | }, 2301 | "require-dev": { 2302 | "phpunit/phpunit": "^6.0" 2303 | }, 2304 | "type": "library", 2305 | "extra": { 2306 | "branch-alias": { 2307 | "dev-master": "1.1-dev" 2308 | } 2309 | }, 2310 | "autoload": { 2311 | "classmap": [ 2312 | "src/" 2313 | ] 2314 | }, 2315 | "notification-url": "https://packagist.org/downloads/", 2316 | "license": [ 2317 | "BSD-3-Clause" 2318 | ], 2319 | "authors": [ 2320 | { 2321 | "name": "Sebastian Bergmann", 2322 | "email": "sebastian@phpunit.de" 2323 | } 2324 | ], 2325 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 2326 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 2327 | "time": "2017-03-29T09:07:27+00:00" 2328 | }, 2329 | { 2330 | "name": "sebastian/recursion-context", 2331 | "version": "3.0.0", 2332 | "source": { 2333 | "type": "git", 2334 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 2335 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" 2336 | }, 2337 | "dist": { 2338 | "type": "zip", 2339 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", 2340 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", 2341 | "shasum": "" 2342 | }, 2343 | "require": { 2344 | "php": "^7.0" 2345 | }, 2346 | "require-dev": { 2347 | "phpunit/phpunit": "^6.0" 2348 | }, 2349 | "type": "library", 2350 | "extra": { 2351 | "branch-alias": { 2352 | "dev-master": "3.0.x-dev" 2353 | } 2354 | }, 2355 | "autoload": { 2356 | "classmap": [ 2357 | "src/" 2358 | ] 2359 | }, 2360 | "notification-url": "https://packagist.org/downloads/", 2361 | "license": [ 2362 | "BSD-3-Clause" 2363 | ], 2364 | "authors": [ 2365 | { 2366 | "name": "Jeff Welch", 2367 | "email": "whatthejeff@gmail.com" 2368 | }, 2369 | { 2370 | "name": "Sebastian Bergmann", 2371 | "email": "sebastian@phpunit.de" 2372 | }, 2373 | { 2374 | "name": "Adam Harvey", 2375 | "email": "aharvey@php.net" 2376 | } 2377 | ], 2378 | "description": "Provides functionality to recursively process PHP variables", 2379 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 2380 | "time": "2017-03-03T06:23:57+00:00" 2381 | }, 2382 | { 2383 | "name": "sebastian/resource-operations", 2384 | "version": "1.0.0", 2385 | "source": { 2386 | "type": "git", 2387 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 2388 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 2389 | }, 2390 | "dist": { 2391 | "type": "zip", 2392 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 2393 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 2394 | "shasum": "" 2395 | }, 2396 | "require": { 2397 | "php": ">=5.6.0" 2398 | }, 2399 | "type": "library", 2400 | "extra": { 2401 | "branch-alias": { 2402 | "dev-master": "1.0.x-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 | "description": "Provides a list of PHP built-in functions that operate on resources", 2421 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 2422 | "time": "2015-07-28T20:34:47+00:00" 2423 | }, 2424 | { 2425 | "name": "sebastian/version", 2426 | "version": "2.0.1", 2427 | "source": { 2428 | "type": "git", 2429 | "url": "https://github.com/sebastianbergmann/version.git", 2430 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" 2431 | }, 2432 | "dist": { 2433 | "type": "zip", 2434 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", 2435 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", 2436 | "shasum": "" 2437 | }, 2438 | "require": { 2439 | "php": ">=5.6" 2440 | }, 2441 | "type": "library", 2442 | "extra": { 2443 | "branch-alias": { 2444 | "dev-master": "2.0.x-dev" 2445 | } 2446 | }, 2447 | "autoload": { 2448 | "classmap": [ 2449 | "src/" 2450 | ] 2451 | }, 2452 | "notification-url": "https://packagist.org/downloads/", 2453 | "license": [ 2454 | "BSD-3-Clause" 2455 | ], 2456 | "authors": [ 2457 | { 2458 | "name": "Sebastian Bergmann", 2459 | "email": "sebastian@phpunit.de", 2460 | "role": "lead" 2461 | } 2462 | ], 2463 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 2464 | "homepage": "https://github.com/sebastianbergmann/version", 2465 | "time": "2016-10-03T07:35:21+00:00" 2466 | }, 2467 | { 2468 | "name": "theseer/tokenizer", 2469 | "version": "1.1.0", 2470 | "source": { 2471 | "type": "git", 2472 | "url": "https://github.com/theseer/tokenizer.git", 2473 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" 2474 | }, 2475 | "dist": { 2476 | "type": "zip", 2477 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", 2478 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", 2479 | "shasum": "" 2480 | }, 2481 | "require": { 2482 | "ext-dom": "*", 2483 | "ext-tokenizer": "*", 2484 | "ext-xmlwriter": "*", 2485 | "php": "^7.0" 2486 | }, 2487 | "type": "library", 2488 | "autoload": { 2489 | "classmap": [ 2490 | "src/" 2491 | ] 2492 | }, 2493 | "notification-url": "https://packagist.org/downloads/", 2494 | "license": [ 2495 | "BSD-3-Clause" 2496 | ], 2497 | "authors": [ 2498 | { 2499 | "name": "Arne Blankerts", 2500 | "email": "arne@blankerts.de", 2501 | "role": "Developer" 2502 | } 2503 | ], 2504 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 2505 | "time": "2017-04-07T12:08:54+00:00" 2506 | }, 2507 | { 2508 | "name": "webmozart/assert", 2509 | "version": "1.3.0", 2510 | "source": { 2511 | "type": "git", 2512 | "url": "https://github.com/webmozart/assert.git", 2513 | "reference": "0df1908962e7a3071564e857d86874dad1ef204a" 2514 | }, 2515 | "dist": { 2516 | "type": "zip", 2517 | "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", 2518 | "reference": "0df1908962e7a3071564e857d86874dad1ef204a", 2519 | "shasum": "" 2520 | }, 2521 | "require": { 2522 | "php": "^5.3.3 || ^7.0" 2523 | }, 2524 | "require-dev": { 2525 | "phpunit/phpunit": "^4.6", 2526 | "sebastian/version": "^1.0.1" 2527 | }, 2528 | "type": "library", 2529 | "extra": { 2530 | "branch-alias": { 2531 | "dev-master": "1.3-dev" 2532 | } 2533 | }, 2534 | "autoload": { 2535 | "psr-4": { 2536 | "Webmozart\\Assert\\": "src/" 2537 | } 2538 | }, 2539 | "notification-url": "https://packagist.org/downloads/", 2540 | "license": [ 2541 | "MIT" 2542 | ], 2543 | "authors": [ 2544 | { 2545 | "name": "Bernhard Schussek", 2546 | "email": "bschussek@gmail.com" 2547 | } 2548 | ], 2549 | "description": "Assertions to validate method input/output with nice error messages.", 2550 | "keywords": [ 2551 | "assert", 2552 | "check", 2553 | "validate" 2554 | ], 2555 | "time": "2018-01-29T19:49:41+00:00" 2556 | } 2557 | ], 2558 | "aliases": [], 2559 | "minimum-stability": "stable", 2560 | "stability-flags": [], 2561 | "prefer-stable": false, 2562 | "prefer-lowest": false, 2563 | "platform": { 2564 | "php": "^7.1" 2565 | }, 2566 | "platform-dev": [] 2567 | } 2568 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | ./tests/ 17 | 18 | 19 | 20 | 21 | 22 | ./src/ 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Async/AbstractConnection.php: -------------------------------------------------------------------------------- 1 | loop = $loop; 37 | 38 | $this->on('close', function () { 39 | $ex = new \RuntimeException('Connection terminated'); 40 | foreach ($this->messages as $definition) { 41 | list(, $reject) = $definition; 42 | $reject($ex); 43 | } 44 | }); 45 | } 46 | 47 | public function enable(array $domains): PromiseInterface 48 | { 49 | $promises = []; 50 | 51 | foreach ($domains as $domain) { 52 | $promises[] = $this->send($domain . '.enable'); 53 | } 54 | 55 | return all($promises)->then(function () use ($domains) { 56 | $out = []; 57 | 58 | foreach ($domains as $domain) { 59 | $out[] = $this->getDomain($domain); 60 | } 61 | 62 | return $out; 63 | }); 64 | } 65 | 66 | public function getDomain(string $name): Domain 67 | { 68 | return array_key_exists($name, $this->domains) 69 | ? $this->domains[$name] 70 | : $this->domains[$name] = new Domain($this, $name); 71 | } 72 | 73 | public function getLoop(): LoopInterface 74 | { 75 | return $this->loop; 76 | } 77 | 78 | protected function handleMessage($msg) 79 | { 80 | if (!($data = json_decode($msg)) || !is_object($data)) { 81 | throw new \RuntimeException('Unable to parse message: ' . $msg); 82 | } 83 | 84 | $this->emit('receive', [$data]); 85 | 86 | if (property_exists($data, 'method')) { 87 | $this->emit($data->method, [$data->params]); 88 | 89 | } else if (property_exists($data, 'id')) { 90 | $this->handleResponse($data); 91 | 92 | } else if (property_exists($data, 'error')) { 93 | $this->handleProtocolError($data); 94 | } 95 | } 96 | 97 | protected function handleResponse(\stdClass $data): void 98 | { 99 | if (!empty($this->messages[$data->id])) { 100 | list($resolve, $err) = $this->messages[$data->id]; 101 | 102 | if (empty($data)) { 103 | $this->emit('error', [$ex = new \RuntimeException('Empty response')]); 104 | $err($ex); 105 | return; 106 | } 107 | 108 | if (!empty($data->error)) { 109 | $this->handleProtocolError($data, $err); 110 | return; 111 | } 112 | 113 | $resolve($data->result); 114 | unset($this->messages[$data->id]); 115 | } 116 | } 117 | 118 | protected function handleProtocolError(\stdClass $data, callable $handler = null): void 119 | { 120 | $details = !empty($data->error->message) ? $data->error->message : 'Unknown Protocol Exception'; 121 | $ex = new ProtocolErrorException($details, $data->error->code); 122 | 123 | $this->emit('error', [$ex]); 124 | 125 | if ($handler) { 126 | $handler($ex); 127 | } 128 | } 129 | 130 | public function __get($name): Domain 131 | { 132 | return $this->getDomain($name); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/Async/Client.php: -------------------------------------------------------------------------------- 1 | '127.0.0.1', 46 | 'port' => 9222, 47 | 'ssl' => false, 48 | 'subProtocols' => [], 49 | 'connectionHeaders' => [], 50 | 'ws_proxy' => null 51 | ]; 52 | 53 | public function __construct(LoopInterface $loop = null, ConnectorInterface $connector = null) 54 | { 55 | $this->loop = $loop ?: Factory::create(); 56 | $this->connector = $connector ?: new Connector($this->loop); 57 | $this->browser = new Browser($this->loop, $this->connector); 58 | $this->applyOptions(); 59 | } 60 | 61 | public function withOptions(array $options = []) 62 | { 63 | $client = clone $this; 64 | $client->applyOptions($options); 65 | return $client; 66 | } 67 | 68 | public function new(): PromiseInterface 69 | { 70 | return $this->request('POST', '/json/new'); 71 | } 72 | 73 | public function list(): PromiseInterface 74 | { 75 | return $this->request('GET', '/json'); 76 | } 77 | 78 | public function version(): PromiseInterface 79 | { 80 | return $this->request('GET', '/json/version'); 81 | } 82 | 83 | public function activate(string $pageId): PromiseInterface 84 | { 85 | return $this->request('POST', '/json/activate/' . $pageId); 86 | } 87 | 88 | public function close(string $pageId): PromiseInterface 89 | { 90 | return $this->request('POST', '/json/close/' . $pageId); 91 | } 92 | 93 | public function getLoop(): LoopInterface 94 | { 95 | return $this->loop; 96 | } 97 | 98 | public function connect(string $url): PromiseInterface 99 | { 100 | if (!empty($this->options['ws_proxy'])) { 101 | $url = $this->getWebsocketProxyUrl($url); 102 | } 103 | 104 | $connector = new \Ratchet\Client\Connector($this->loop, $this->connector); 105 | 106 | return $connector($url, $this->options['subProtocols'], $this->options['connectionHeaders']) 107 | ->then(function ($socket) use ($url) { 108 | return new Connection($socket, $this->loop); 109 | }); 110 | } 111 | 112 | public function request(string $method, string $endpoint, array $headers = [], $body = ''): PromiseInterface 113 | { 114 | $request = new \RingCentral\Psr7\Request($method, $endpoint, $headers, stream_for($body), '1.1'); 115 | return $this->send($request); 116 | } 117 | 118 | public function send(RequestInterface $request) 119 | { 120 | $this->emit('request', [$request]); 121 | 122 | return new Promise(function ($resolve, $reject) use ($request) { 123 | $this->browser 124 | ->send($request) 125 | ->then(function (ResponseInterface $response) use ($resolve, $reject) { 126 | /* @var $body \React\Stream\ReadableStreamInterface */ 127 | $body = $response->getBody(); 128 | $totalBytes = intval($response->getHeaderLine('content-length')); 129 | $downloadedBytes = 0; 130 | $data = ''; 131 | 132 | $body->on('data', function ($chunk) use ($body, &$data, &$downloadedBytes, $totalBytes) { 133 | $downloadedBytes += strlen($chunk); 134 | $data .= $chunk; 135 | 136 | if ($downloadedBytes >= $totalBytes) { 137 | $body->close(); 138 | } 139 | }); 140 | 141 | $body->on('error', function (\Exception $error) use ($reject) { 142 | $reject($error); 143 | }); 144 | 145 | $body->on('close', function () use ($resolve, $reject, $response, &$data, &$downloadedBytes, $totalBytes) { 146 | if ($downloadedBytes !== $totalBytes) { 147 | $reject(new \RuntimeException("Chrome response error: Expected $totalBytes bytes got $downloadedBytes bytes.")); 148 | } else { 149 | $this->emit('response', [ 150 | new Response($response->getStatusCode(), $response->getHeaders(), $data) 151 | ]); 152 | 153 | $resolve(json_decode($data)); 154 | } 155 | }); 156 | }, $reject); 157 | }); 158 | } 159 | 160 | private function getWebsocketProxyUrl($url): string 161 | { 162 | $oldBase = 'ws://' . $this->options['host'] . ':' . $this->options['port']; 163 | 164 | $config = $this->options['ws_proxy']; 165 | $host = array_key_exists('host', $config) ? $config['host'] : $this->options['host']; 166 | $port = array_key_exists('port', $config) ? $config['port'] : $this->options['port']; 167 | $ssl = array_key_exists('ssl', $config) ? $config['ssl'] : $this->options['ssl']; 168 | 169 | return substr_replace($url, "ws" . ($ssl ? 's' : '') . "://$host:$port", 0, strlen($oldBase)); 170 | } 171 | 172 | private function applyOptions(array $options = []): void 173 | { 174 | $this->options = $options + $this->options; 175 | $this->base = $this->options['host'] . ':' . $this->options['port']; 176 | $this->browser = $this->browser 177 | ->withBase("http" . ($this->options['ssl'] ? 's' : '') . "://" . $this->base) 178 | ->withOptions(['streaming' => true]); 179 | } 180 | } -------------------------------------------------------------------------------- /src/Async/Connection.php: -------------------------------------------------------------------------------- 1 | socket = $socket; 27 | 28 | $socket 29 | ->on('message', function ($msg) { 30 | $this->handleMessage($msg); 31 | }) 32 | ->on('error', function ($err) { 33 | $this->emit('error', [$err]); 34 | }) 35 | ->on('close', function () { 36 | $this->emit('close'); 37 | }); 38 | 39 | $this 40 | ->on('Target.receivedMessageFromTarget', function ($event) { 41 | $this->sendToSession($event->sessionId, 'message', [$event->message]); 42 | }) 43 | ->on('Target.detachedFromTarget', function ($event) { 44 | $this->sendToSession($event->sessionId, 'close'); 45 | unset($this->sessions[$event->sessionId]); 46 | }); 47 | } 48 | 49 | public function send(string $method, array $params = []): PromiseInterface 50 | { 51 | $args = new \stdClass; 52 | $args->id = $this->messageId++; 53 | $args->method = $method; 54 | $args->params = $params; 55 | 56 | $this->emit('send', [$args]); 57 | 58 | return new Promise(function ($resolve, $err) use ($args) { 59 | $this->messages[$args->id] = [$resolve, $err]; 60 | $this->socket->send(json_encode($args)); 61 | }); 62 | } 63 | 64 | public function disconnect() 65 | { 66 | $this->socket->close(); 67 | } 68 | 69 | public function createSession($targetId): PromiseInterface 70 | { 71 | return $this 72 | ->send('Target.attachToTarget', ['targetId' => $targetId]) 73 | ->then(function ($response) use ($targetId) { 74 | return $this->sessions[$response->sessionId] = new Session($this, $response->sessionId); 75 | }); 76 | } 77 | 78 | private function sendToSession($sessionId, $event, $params = null) 79 | { 80 | if (!array_key_exists($sessionId, $this->sessions)) { 81 | throw new \RuntimeException('Cannot send message to detached session'); 82 | } 83 | 84 | $this->sessions[$sessionId]->emit($event, $params); 85 | } 86 | } -------------------------------------------------------------------------------- /src/Async/Domain.php: -------------------------------------------------------------------------------- 1 | connection = $connection; 24 | $this->domain = $domain; 25 | } 26 | 27 | public function enable(): PromiseInterface 28 | { 29 | return $this->connection->enable([$this->domain])->then(function () { 30 | return $this; 31 | }); 32 | } 33 | 34 | public function on($event, callable $callable): DomainInterface 35 | { 36 | $this->connection->on($this->withDomain($event), $callable); 37 | return $this; 38 | } 39 | 40 | public function send($method, $args = []): PromiseInterface 41 | { 42 | return $this->connection->send($this->withDomain($method), $args); 43 | } 44 | 45 | public function __call($method, $arguments): PromiseInterface 46 | { 47 | $args = !empty($arguments) ? $arguments[0] : []; 48 | return $this->send($method, $args); 49 | } 50 | 51 | private function withDomain($symbol): string 52 | { 53 | return ($this->domain ? $this->domain . '.' : '') . $symbol; 54 | } 55 | 56 | public function getLoop(): LoopInterface 57 | { 58 | return $this->connection->getLoop(); 59 | } 60 | } -------------------------------------------------------------------------------- /src/Async/Session.php: -------------------------------------------------------------------------------- 1 | getLoop()); 23 | $this->connection = $connection; 24 | $this->sessionId = $sessionId; 25 | 26 | $this->connection 27 | ->on('close', function () { 28 | $this->emit('close'); 29 | }) 30 | ->on('error', function ($err) { 31 | $this->emit('error', [$err]); 32 | }); 33 | 34 | $this->on('message', function ($msg) { 35 | $this->handleMessage($msg); 36 | }); 37 | } 38 | 39 | public function send(string $method, array $params = []): PromiseInterface 40 | { 41 | $args = new \stdClass; 42 | $args->id = $this->messageId++; 43 | $args->method = $method; 44 | $args->params = $params; 45 | 46 | $promise = new Promise(function ($resolve, $err) use ($args) { 47 | $this->messages[$args->id] = [$resolve, $err]; 48 | }); 49 | 50 | return $this->connection 51 | ->send('Target.sendMessageToTarget', [ 52 | 'sessionId' => $this->sessionId, 53 | 'message' => json_encode($args) 54 | ]) 55 | ->then(function () use ($promise) { 56 | return $promise; 57 | }); 58 | } 59 | 60 | public function disconnect() 61 | { 62 | $this->connection->send('Target.detachFromTarget'); 63 | } 64 | 65 | /** 66 | * @internal 67 | */ 68 | public function createSession($targetId) 69 | { 70 | throw new \RuntimeException('Sessions cannot be initialized recursively.'); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Blocking/BlockTrait.php: -------------------------------------------------------------------------------- 1 | getLoop(), is_null($timeout) ? $this->timeout : $timeout); 19 | } 20 | } -------------------------------------------------------------------------------- /src/Blocking/Client.php: -------------------------------------------------------------------------------- 1 | client = $client ?: new AsyncClient; 23 | } 24 | 25 | public function withOptions(array $options = []) 26 | { 27 | $clone = clone $this; 28 | $clone->client = $clone->client->withOptions($options); 29 | 30 | if (array_key_exists('timeout', $options)) { 31 | $this->timeout = $options['timeout']; 32 | } 33 | 34 | return $clone; 35 | } 36 | 37 | public function new(int $timeout = null) 38 | { 39 | return $this->block($this->client->new(), $timeout); 40 | } 41 | 42 | public function list(int $timeout = null) 43 | { 44 | return $this->block($this->client->list(), $timeout); 45 | } 46 | 47 | public function version(int $timeout = null) 48 | { 49 | return $this->block($this->client->version(), $timeout); 50 | } 51 | 52 | public function activate(string $pageId, int $timeout = null) 53 | { 54 | return $this->block($this->client->activate($pageId), $timeout); 55 | } 56 | 57 | public function close(string $pageId, int $timeout = null) 58 | { 59 | return $this->block($this->client->close($pageId), $timeout); 60 | } 61 | 62 | public function getLoop(): LoopInterface 63 | { 64 | return $this->client->getLoop(); 65 | } 66 | 67 | public function connect(string $url, int $timeout = null) 68 | { 69 | return new Connection($this->block($this->client->connect($url), $timeout), $this->timeout); 70 | } 71 | 72 | public function send(RequestInterface $request, int $timeout = null) 73 | { 74 | return $this->block($this->client->send($request), $timeout); 75 | } 76 | 77 | public function request(string $method, string $endpoint, array $headers = [], $body = '', int $timeout = null) 78 | { 79 | return $this->block($this->client->request($method, $endpoint, $headers, $body), $timeout); 80 | } 81 | 82 | protected function getEmitter(): EventEmitterInterface 83 | { 84 | return $this->client; 85 | } 86 | } -------------------------------------------------------------------------------- /src/Blocking/Connection.php: -------------------------------------------------------------------------------- 1 | deferred = new Deferred; 30 | $this->connection = $connection; 31 | $this->timeout = $timeout; 32 | 33 | $this->connection 34 | ->on('error', function ($error) { 35 | $this->deferred->reject($error); 36 | }) 37 | ->on('close', function () { 38 | $this->deferred->resolve(); 39 | }); 40 | } 41 | 42 | public function waitUntilDisconnect(int $timeout = null) 43 | { 44 | return $this->block($this->deferred->promise(), $timeout); 45 | } 46 | 47 | public function send(string $method, array $params = [], int $timeout = null): \stdClass 48 | { 49 | return $this->block($this->connection->send($method, $params), $timeout); 50 | } 51 | 52 | public function enable(array $domains, int $timeout = null): array 53 | { 54 | return $this->block($this->connection->enable($domains), $timeout); 55 | } 56 | 57 | public function disconnect() 58 | { 59 | $this->connection->disconnect(); 60 | } 61 | 62 | public function createSession($targetId, int $timeout = null) : Connection 63 | { 64 | $session = $this->block($this->connection->createSession($targetId), $timeout); 65 | return new Connection($session, $this->timeout); 66 | } 67 | 68 | public function getDomain(string $name): DomainInterface 69 | { 70 | return new Domain($this->connection->getDomain($name), $this->timeout); 71 | } 72 | 73 | public function __get($name): DomainInterface 74 | { 75 | return $this->getDomain($name); 76 | } 77 | 78 | public function getLoop(): LoopInterface 79 | { 80 | return $this->connection->getLoop(); 81 | } 82 | 83 | protected function getEmitter(): EventEmitterInterface 84 | { 85 | return $this->connection; 86 | } 87 | } -------------------------------------------------------------------------------- /src/Blocking/Domain.php: -------------------------------------------------------------------------------- 1 | domain = $domain; 22 | $this->timeout = $timeout; 23 | } 24 | 25 | public function enable(int $timeout = null) 26 | { 27 | return $this->block($this->domain->enable(), $timeout); 28 | } 29 | 30 | public function on($event, callable $callable): DomainInterface 31 | { 32 | $this->domain->on($event, $callable); 33 | return $this; 34 | } 35 | 36 | public function send($method, $args = [], int $timeout = null) 37 | { 38 | return $this->block($this->domain->send($method, $args), $timeout); 39 | } 40 | 41 | public function getLoop(): LoopInterface 42 | { 43 | return $this->domain->getLoop(); 44 | } 45 | 46 | public function __call($method, $arguments = []) 47 | { 48 | $args = array_shift($arguments); 49 | $timeout = !empty($arguments) ? $arguments[0] : null; 50 | 51 | return $this->block($this->domain->$method($args), $timeout); 52 | } 53 | } -------------------------------------------------------------------------------- /src/Blocking/EventHandlerTrait.php: -------------------------------------------------------------------------------- 1 | getEmitter()->on($event, $listener); 16 | return $this; 17 | } 18 | 19 | public function once($event, callable $listener) 20 | { 21 | $promise = new Promise(function ($resolve) use ($event, $listener) { 22 | $this->getEmitter()->once($event, function ($result) use ($resolve, $listener) { 23 | $resolve($listener($result)); 24 | }); 25 | }); 26 | 27 | $this->getEmitter()->once('close', [$promise, 'cancel']); 28 | 29 | return $this->block($promise); 30 | } 31 | 32 | public function removeListener($event, callable $listener) 33 | { 34 | $this->getEmitter()->removeListener($event, $listener); 35 | } 36 | 37 | public function removeAllListeners($event = null) 38 | { 39 | $this->getEmitter()->removeAllListeners($event); 40 | } 41 | 42 | public function listeners($event = null) 43 | { 44 | return $this->getEmitter()->listeners($event); 45 | } 46 | 47 | public function emit($event, array $arguments = []) 48 | { 49 | $this->getEmitter()->emit($event, $arguments); 50 | } 51 | 52 | protected abstract function getLoop(): LoopInterface; 53 | 54 | protected abstract function getEmitter(): EventEmitterInterface; 55 | } -------------------------------------------------------------------------------- /src/ClientInterface.php: -------------------------------------------------------------------------------- 1 |