├── .gitignore ├── .phpstorm.meta.php ├── README.md ├── composer.json ├── composer.lock ├── container.php ├── data └── .gitignore ├── phpunit.xml.dist ├── public ├── .gitignore └── index.php ├── src ├── Domain │ ├── Aggregate │ │ └── Building.php │ ├── Command │ │ └── RegisterNewBuilding.php │ ├── DomainEvent │ │ └── NewBuildingWasRegistered.php │ └── Repository │ │ └── BuildingRepositoryInterface.php └── Infrastructure │ └── Repository │ └── BuildingRepository.php ├── template ├── building.php └── index.php └── worker └── worker.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor -------------------------------------------------------------------------------- /.phpstorm.meta.php: -------------------------------------------------------------------------------- 1 | [ 7 | "" == "@", 8 | ], 9 | ]; 10 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Basic CQRS and Event Sourcing with Prooph 2 | 3 | This is an example application aimed at teaching basic event sourcing. 4 | 5 | #### Requirements 6 | 7 | To run this application, you will need: 8 | 9 | * [PHP 7](https://secure.php.net/downloads.php) 10 | * [composer](https://getcomposer.org/) 11 | * [ext-pdo](http://php.net/manual/en/book.pdo.php) 12 | * [ext-pdo_sqlite](http://php.net/manual/en/ref.pdo-sqlite.php) 13 | 14 | #### Toolchain 15 | 16 | The tools that we are going to use are: 17 | 18 | * [Zend Expressive](https://github.com/zendframework/zend-expressive) a simple PSR-7/HTTP routing framework 19 | * [Prooph Components](https://github.com/prooph/) abstraction for common CQRS + Event Sourcing concerns 20 | 21 | #### Domain of the app 22 | 23 | The domain of the application is quite limited, but sufficient to explain how and when to effectively use 24 | CQRS and EventSourcing. 25 | 26 | The MVP of the application has following specification: 27 | 28 | * assume that each person interacting with the system has a badge with a username on it 29 | * assume that the username is given: we assume that the input data is already validated against existing users 30 | * track people entering (check-in) a building 31 | * track people leaving (check-out) a building 32 | * prevent people from double-entering a building (security concern) 33 | * prevent people from double-leaving a building (security concern) 34 | * allow querying a list of people that are currently in the building 35 | 36 | #### Build steps 37 | 38 | Following steps are to be implemented: 39 | 40 | - [x] Ability to register a new building (already provided) 41 | - [ ] Ability to check-in with a username and a building identifier (skeleton code provided) 42 | - [ ] Ability to check-out with a username and a building identifier (skeleton code provided) 43 | - [ ] Provide console output (STDERR) every time a check-in happens (event handler) 44 | - [ ] Provide console output (STDERR) every time a check-out happens (event handler) 45 | - [ ] Provide a file per building (accessible via HTTP) with usernames of currently checked-in persons 46 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php": "^7.0", 4 | "ext-pdo": "*", 5 | "ext-pdo_sqlite": "*", 6 | "bernard/bernard": "^1.0@DEV", 7 | "doctrine/dbal": "~2.5", 8 | "filp/whoops": "^2.1", 9 | "prooph/event-sourcing": "~4.0", 10 | "prooph/event-store": "^6.0", 11 | "prooph/event-store-bus-bridge": "^2.0", 12 | "prooph/event-store-doctrine-adapter": "^3.0", 13 | "prooph/psb-bernard-producer": "^2.0", 14 | "prooph/service-bus": "~5.0", 15 | "zendframework/zend-expressive": "^1.0.0", 16 | "zendframework/zend-expressive-fastroute": "^1.0", 17 | "zendframework/zend-servicemanager": "^3.0" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "Building\\": "src/" 22 | } 23 | }, 24 | "scripts": { 25 | "serve": "php -S 0.0.0.0:8080 -t public/" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /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": "d27ad5e556afaf6ed1fad63ded0202b6", 8 | "packages": [ 9 | { 10 | "name": "beberlei/assert", 11 | "version": "v2.6.3", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/beberlei/assert.git", 15 | "reference": "51e9d654481fc00c8a376641c390ec4e35d8c1fc" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/beberlei/assert/zipball/51e9d654481fc00c8a376641c390ec4e35d8c1fc", 20 | "reference": "51e9d654481fc00c8a376641c390ec4e35d8c1fc", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "ext-mbstring": "*", 25 | "php": ">=5.3" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "@stable" 29 | }, 30 | "type": "library", 31 | "extra": { 32 | "branch-alias": { 33 | "dev-master": "2.5-dev" 34 | } 35 | }, 36 | "autoload": { 37 | "psr-0": { 38 | "Assert": "lib/" 39 | }, 40 | "files": [ 41 | "lib/Assert/functions.php" 42 | ] 43 | }, 44 | "notification-url": "https://packagist.org/downloads/", 45 | "license": [ 46 | "BSD-2-Clause" 47 | ], 48 | "authors": [ 49 | { 50 | "name": "Benjamin Eberlei", 51 | "email": "kontakt@beberlei.de", 52 | "role": "Lead Developer" 53 | }, 54 | { 55 | "name": "Richard Quadling", 56 | "email": "rquadling@gmail.com", 57 | "role": "Collaborator" 58 | } 59 | ], 60 | "description": "Thin assertion library for input validation in business models.", 61 | "keywords": [ 62 | "assert", 63 | "assertion", 64 | "validation" 65 | ], 66 | "time": "2016-07-28 19:35:30" 67 | }, 68 | { 69 | "name": "bernard/bernard", 70 | "version": "dev-master", 71 | "source": { 72 | "type": "git", 73 | "url": "https://github.com/bernardphp/bernard.git", 74 | "reference": "ec54820b006142f909e32d915b260749bb94ea04" 75 | }, 76 | "dist": { 77 | "type": "zip", 78 | "url": "https://api.github.com/repos/bernardphp/bernard/zipball/ec54820b006142f909e32d915b260749bb94ea04", 79 | "reference": "ec54820b006142f909e32d915b260749bb94ea04", 80 | "shasum": "" 81 | }, 82 | "require": { 83 | "beberlei/assert": "~2.1", 84 | "bernard/normalt": "~1.0", 85 | "php": "~5.4|~7.0", 86 | "symfony/event-dispatcher": "~2.3|~3.0" 87 | }, 88 | "require-dev": { 89 | "aws/aws-sdk-php": "~2.4|~3.0", 90 | "doctrine/dbal": "~2.3", 91 | "iron-io/iron_mq": "~1.4", 92 | "league/container": "~1.0", 93 | "pda/pheanstalk": "~3.0", 94 | "php-amqplib/php-amqplib": "~2.5", 95 | "phpspec/phpspec": "~2.0", 96 | "pimple/pimple": "~1.0", 97 | "predis/predis": "~0.8", 98 | "psr/log": "~1.0", 99 | "symfony/console": "~2.3|~3.0", 100 | "symfony/dependency-injection": "~2.3|~3.0" 101 | }, 102 | "suggest": { 103 | "aws/aws-sdk-php": "Allow sending messages to AWS services like Simple Queue Service", 104 | "doctrine/dbal": "Allow sending messages to simulated message queue in a database via doctrine dbal", 105 | "iron-io/iron_mq": "Allow sending messages to IronMQ", 106 | "mongodb/mongodb": "Allow sending messages to a MongoDB server via PHP Driver", 107 | "pda/pheanstalk": "Allow sending messages to Beanstalk using pheanstalk", 108 | "php-amqplib/php-amqplib": "Allow sending messages to an AMQP server using php-amqplib", 109 | "predis/predis": "Allow sending messages to Redis using predis" 110 | }, 111 | "type": "library", 112 | "extra": { 113 | "branch-alias": { 114 | "dev-master": "1.0.x-dev" 115 | } 116 | }, 117 | "autoload": { 118 | "psr-4": { 119 | "Bernard\\": "src/" 120 | } 121 | }, 122 | "notification-url": "https://packagist.org/downloads/", 123 | "license": [ 124 | "MIT" 125 | ], 126 | "description": "Message queue implemented in PHP with Redis as a backend.", 127 | "homepage": "https://github.com/bernardphp/bernard", 128 | "keywords": [ 129 | "bernard", 130 | "message", 131 | "message queue", 132 | "queue" 133 | ], 134 | "time": "2016-09-09 12:28:21" 135 | }, 136 | { 137 | "name": "bernard/normalt", 138 | "version": "1.1.0", 139 | "source": { 140 | "type": "git", 141 | "url": "https://github.com/bernardphp/normalt.git", 142 | "reference": "1cde16b1a2a5a20964c3e2fea66e2b98c3f57d41" 143 | }, 144 | "dist": { 145 | "type": "zip", 146 | "url": "https://api.github.com/repos/bernardphp/normalt/zipball/1cde16b1a2a5a20964c3e2fea66e2b98c3f57d41", 147 | "reference": "1cde16b1a2a5a20964c3e2fea66e2b98c3f57d41", 148 | "shasum": "" 149 | }, 150 | "require": { 151 | "symfony/serializer": "^2.3 || ^3.0" 152 | }, 153 | "require-dev": { 154 | "doctrine/common": "^2.1", 155 | "phpspec/phpspec": "^2.5" 156 | }, 157 | "type": "library", 158 | "extra": { 159 | "branch-alias": { 160 | "dev-master": "1.1-dev" 161 | } 162 | }, 163 | "autoload": { 164 | "psr-4": { 165 | "Normalt\\": "src/" 166 | } 167 | }, 168 | "notification-url": "https://packagist.org/downloads/", 169 | "license": [ 170 | "MIT" 171 | ], 172 | "description": "Normalt is a extension to Symfony Serializer that only implements the Normalization part", 173 | "keywords": [ 174 | "denormalization", 175 | "normalization" 176 | ], 177 | "time": "2016-05-03 08:09:59" 178 | }, 179 | { 180 | "name": "container-interop/container-interop", 181 | "version": "1.1.0", 182 | "source": { 183 | "type": "git", 184 | "url": "https://github.com/container-interop/container-interop.git", 185 | "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e" 186 | }, 187 | "dist": { 188 | "type": "zip", 189 | "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e", 190 | "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e", 191 | "shasum": "" 192 | }, 193 | "type": "library", 194 | "autoload": { 195 | "psr-4": { 196 | "Interop\\Container\\": "src/Interop/Container/" 197 | } 198 | }, 199 | "notification-url": "https://packagist.org/downloads/", 200 | "license": [ 201 | "MIT" 202 | ], 203 | "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", 204 | "time": "2014-12-30 15:22:37" 205 | }, 206 | { 207 | "name": "doctrine/annotations", 208 | "version": "v1.2.7", 209 | "source": { 210 | "type": "git", 211 | "url": "https://github.com/doctrine/annotations.git", 212 | "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" 213 | }, 214 | "dist": { 215 | "type": "zip", 216 | "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", 217 | "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", 218 | "shasum": "" 219 | }, 220 | "require": { 221 | "doctrine/lexer": "1.*", 222 | "php": ">=5.3.2" 223 | }, 224 | "require-dev": { 225 | "doctrine/cache": "1.*", 226 | "phpunit/phpunit": "4.*" 227 | }, 228 | "type": "library", 229 | "extra": { 230 | "branch-alias": { 231 | "dev-master": "1.3.x-dev" 232 | } 233 | }, 234 | "autoload": { 235 | "psr-0": { 236 | "Doctrine\\Common\\Annotations\\": "lib/" 237 | } 238 | }, 239 | "notification-url": "https://packagist.org/downloads/", 240 | "license": [ 241 | "MIT" 242 | ], 243 | "authors": [ 244 | { 245 | "name": "Roman Borschel", 246 | "email": "roman@code-factory.org" 247 | }, 248 | { 249 | "name": "Benjamin Eberlei", 250 | "email": "kontakt@beberlei.de" 251 | }, 252 | { 253 | "name": "Guilherme Blanco", 254 | "email": "guilhermeblanco@gmail.com" 255 | }, 256 | { 257 | "name": "Jonathan Wage", 258 | "email": "jonwage@gmail.com" 259 | }, 260 | { 261 | "name": "Johannes Schmitt", 262 | "email": "schmittjoh@gmail.com" 263 | } 264 | ], 265 | "description": "Docblock Annotations Parser", 266 | "homepage": "http://www.doctrine-project.org", 267 | "keywords": [ 268 | "annotations", 269 | "docblock", 270 | "parser" 271 | ], 272 | "time": "2015-08-31 12:32:49" 273 | }, 274 | { 275 | "name": "doctrine/cache", 276 | "version": "v1.6.0", 277 | "source": { 278 | "type": "git", 279 | "url": "https://github.com/doctrine/cache.git", 280 | "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6" 281 | }, 282 | "dist": { 283 | "type": "zip", 284 | "url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6", 285 | "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6", 286 | "shasum": "" 287 | }, 288 | "require": { 289 | "php": "~5.5|~7.0" 290 | }, 291 | "conflict": { 292 | "doctrine/common": ">2.2,<2.4" 293 | }, 294 | "require-dev": { 295 | "phpunit/phpunit": "~4.8|~5.0", 296 | "predis/predis": "~1.0", 297 | "satooshi/php-coveralls": "~0.6" 298 | }, 299 | "type": "library", 300 | "extra": { 301 | "branch-alias": { 302 | "dev-master": "1.6.x-dev" 303 | } 304 | }, 305 | "autoload": { 306 | "psr-4": { 307 | "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" 308 | } 309 | }, 310 | "notification-url": "https://packagist.org/downloads/", 311 | "license": [ 312 | "MIT" 313 | ], 314 | "authors": [ 315 | { 316 | "name": "Roman Borschel", 317 | "email": "roman@code-factory.org" 318 | }, 319 | { 320 | "name": "Benjamin Eberlei", 321 | "email": "kontakt@beberlei.de" 322 | }, 323 | { 324 | "name": "Guilherme Blanco", 325 | "email": "guilhermeblanco@gmail.com" 326 | }, 327 | { 328 | "name": "Jonathan Wage", 329 | "email": "jonwage@gmail.com" 330 | }, 331 | { 332 | "name": "Johannes Schmitt", 333 | "email": "schmittjoh@gmail.com" 334 | } 335 | ], 336 | "description": "Caching library offering an object-oriented API for many cache backends", 337 | "homepage": "http://www.doctrine-project.org", 338 | "keywords": [ 339 | "cache", 340 | "caching" 341 | ], 342 | "time": "2015-12-31 16:37:02" 343 | }, 344 | { 345 | "name": "doctrine/collections", 346 | "version": "v1.3.0", 347 | "source": { 348 | "type": "git", 349 | "url": "https://github.com/doctrine/collections.git", 350 | "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" 351 | }, 352 | "dist": { 353 | "type": "zip", 354 | "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", 355 | "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", 356 | "shasum": "" 357 | }, 358 | "require": { 359 | "php": ">=5.3.2" 360 | }, 361 | "require-dev": { 362 | "phpunit/phpunit": "~4.0" 363 | }, 364 | "type": "library", 365 | "extra": { 366 | "branch-alias": { 367 | "dev-master": "1.2.x-dev" 368 | } 369 | }, 370 | "autoload": { 371 | "psr-0": { 372 | "Doctrine\\Common\\Collections\\": "lib/" 373 | } 374 | }, 375 | "notification-url": "https://packagist.org/downloads/", 376 | "license": [ 377 | "MIT" 378 | ], 379 | "authors": [ 380 | { 381 | "name": "Roman Borschel", 382 | "email": "roman@code-factory.org" 383 | }, 384 | { 385 | "name": "Benjamin Eberlei", 386 | "email": "kontakt@beberlei.de" 387 | }, 388 | { 389 | "name": "Guilherme Blanco", 390 | "email": "guilhermeblanco@gmail.com" 391 | }, 392 | { 393 | "name": "Jonathan Wage", 394 | "email": "jonwage@gmail.com" 395 | }, 396 | { 397 | "name": "Johannes Schmitt", 398 | "email": "schmittjoh@gmail.com" 399 | } 400 | ], 401 | "description": "Collections Abstraction library", 402 | "homepage": "http://www.doctrine-project.org", 403 | "keywords": [ 404 | "array", 405 | "collections", 406 | "iterator" 407 | ], 408 | "time": "2015-04-14 22:21:58" 409 | }, 410 | { 411 | "name": "doctrine/common", 412 | "version": "v2.6.1", 413 | "source": { 414 | "type": "git", 415 | "url": "https://github.com/doctrine/common.git", 416 | "reference": "a579557bc689580c19fee4e27487a67fe60defc0" 417 | }, 418 | "dist": { 419 | "type": "zip", 420 | "url": "https://api.github.com/repos/doctrine/common/zipball/a579557bc689580c19fee4e27487a67fe60defc0", 421 | "reference": "a579557bc689580c19fee4e27487a67fe60defc0", 422 | "shasum": "" 423 | }, 424 | "require": { 425 | "doctrine/annotations": "1.*", 426 | "doctrine/cache": "1.*", 427 | "doctrine/collections": "1.*", 428 | "doctrine/inflector": "1.*", 429 | "doctrine/lexer": "1.*", 430 | "php": "~5.5|~7.0" 431 | }, 432 | "require-dev": { 433 | "phpunit/phpunit": "~4.8|~5.0" 434 | }, 435 | "type": "library", 436 | "extra": { 437 | "branch-alias": { 438 | "dev-master": "2.7.x-dev" 439 | } 440 | }, 441 | "autoload": { 442 | "psr-4": { 443 | "Doctrine\\Common\\": "lib/Doctrine/Common" 444 | } 445 | }, 446 | "notification-url": "https://packagist.org/downloads/", 447 | "license": [ 448 | "MIT" 449 | ], 450 | "authors": [ 451 | { 452 | "name": "Roman Borschel", 453 | "email": "roman@code-factory.org" 454 | }, 455 | { 456 | "name": "Benjamin Eberlei", 457 | "email": "kontakt@beberlei.de" 458 | }, 459 | { 460 | "name": "Guilherme Blanco", 461 | "email": "guilhermeblanco@gmail.com" 462 | }, 463 | { 464 | "name": "Jonathan Wage", 465 | "email": "jonwage@gmail.com" 466 | }, 467 | { 468 | "name": "Johannes Schmitt", 469 | "email": "schmittjoh@gmail.com" 470 | } 471 | ], 472 | "description": "Common Library for Doctrine projects", 473 | "homepage": "http://www.doctrine-project.org", 474 | "keywords": [ 475 | "annotations", 476 | "collections", 477 | "eventmanager", 478 | "persistence", 479 | "spl" 480 | ], 481 | "time": "2015-12-25 13:18:31" 482 | }, 483 | { 484 | "name": "doctrine/dbal", 485 | "version": "v2.5.5", 486 | "source": { 487 | "type": "git", 488 | "url": "https://github.com/doctrine/dbal.git", 489 | "reference": "9f8c05cd5225a320d56d4bfdb4772f10d045a0c9" 490 | }, 491 | "dist": { 492 | "type": "zip", 493 | "url": "https://api.github.com/repos/doctrine/dbal/zipball/9f8c05cd5225a320d56d4bfdb4772f10d045a0c9", 494 | "reference": "9f8c05cd5225a320d56d4bfdb4772f10d045a0c9", 495 | "shasum": "" 496 | }, 497 | "require": { 498 | "doctrine/common": ">=2.4,<2.7-dev", 499 | "php": ">=5.3.2" 500 | }, 501 | "require-dev": { 502 | "phpunit/phpunit": "4.*", 503 | "symfony/console": "2.*||^3.0" 504 | }, 505 | "suggest": { 506 | "symfony/console": "For helpful console commands such as SQL execution and import of files." 507 | }, 508 | "bin": [ 509 | "bin/doctrine-dbal" 510 | ], 511 | "type": "library", 512 | "extra": { 513 | "branch-alias": { 514 | "dev-master": "2.5.x-dev" 515 | } 516 | }, 517 | "autoload": { 518 | "psr-0": { 519 | "Doctrine\\DBAL\\": "lib/" 520 | } 521 | }, 522 | "notification-url": "https://packagist.org/downloads/", 523 | "license": [ 524 | "MIT" 525 | ], 526 | "authors": [ 527 | { 528 | "name": "Roman Borschel", 529 | "email": "roman@code-factory.org" 530 | }, 531 | { 532 | "name": "Benjamin Eberlei", 533 | "email": "kontakt@beberlei.de" 534 | }, 535 | { 536 | "name": "Guilherme Blanco", 537 | "email": "guilhermeblanco@gmail.com" 538 | }, 539 | { 540 | "name": "Jonathan Wage", 541 | "email": "jonwage@gmail.com" 542 | } 543 | ], 544 | "description": "Database Abstraction Layer", 545 | "homepage": "http://www.doctrine-project.org", 546 | "keywords": [ 547 | "database", 548 | "dbal", 549 | "persistence", 550 | "queryobject" 551 | ], 552 | "time": "2016-09-09 19:13:33" 553 | }, 554 | { 555 | "name": "doctrine/inflector", 556 | "version": "v1.1.0", 557 | "source": { 558 | "type": "git", 559 | "url": "https://github.com/doctrine/inflector.git", 560 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" 561 | }, 562 | "dist": { 563 | "type": "zip", 564 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", 565 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", 566 | "shasum": "" 567 | }, 568 | "require": { 569 | "php": ">=5.3.2" 570 | }, 571 | "require-dev": { 572 | "phpunit/phpunit": "4.*" 573 | }, 574 | "type": "library", 575 | "extra": { 576 | "branch-alias": { 577 | "dev-master": "1.1.x-dev" 578 | } 579 | }, 580 | "autoload": { 581 | "psr-0": { 582 | "Doctrine\\Common\\Inflector\\": "lib/" 583 | } 584 | }, 585 | "notification-url": "https://packagist.org/downloads/", 586 | "license": [ 587 | "MIT" 588 | ], 589 | "authors": [ 590 | { 591 | "name": "Roman Borschel", 592 | "email": "roman@code-factory.org" 593 | }, 594 | { 595 | "name": "Benjamin Eberlei", 596 | "email": "kontakt@beberlei.de" 597 | }, 598 | { 599 | "name": "Guilherme Blanco", 600 | "email": "guilhermeblanco@gmail.com" 601 | }, 602 | { 603 | "name": "Jonathan Wage", 604 | "email": "jonwage@gmail.com" 605 | }, 606 | { 607 | "name": "Johannes Schmitt", 608 | "email": "schmittjoh@gmail.com" 609 | } 610 | ], 611 | "description": "Common String Manipulations with regard to casing and singular/plural rules.", 612 | "homepage": "http://www.doctrine-project.org", 613 | "keywords": [ 614 | "inflection", 615 | "pluralize", 616 | "singularize", 617 | "string" 618 | ], 619 | "time": "2015-11-06 14:35:42" 620 | }, 621 | { 622 | "name": "doctrine/lexer", 623 | "version": "v1.0.1", 624 | "source": { 625 | "type": "git", 626 | "url": "https://github.com/doctrine/lexer.git", 627 | "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" 628 | }, 629 | "dist": { 630 | "type": "zip", 631 | "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", 632 | "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", 633 | "shasum": "" 634 | }, 635 | "require": { 636 | "php": ">=5.3.2" 637 | }, 638 | "type": "library", 639 | "extra": { 640 | "branch-alias": { 641 | "dev-master": "1.0.x-dev" 642 | } 643 | }, 644 | "autoload": { 645 | "psr-0": { 646 | "Doctrine\\Common\\Lexer\\": "lib/" 647 | } 648 | }, 649 | "notification-url": "https://packagist.org/downloads/", 650 | "license": [ 651 | "MIT" 652 | ], 653 | "authors": [ 654 | { 655 | "name": "Roman Borschel", 656 | "email": "roman@code-factory.org" 657 | }, 658 | { 659 | "name": "Guilherme Blanco", 660 | "email": "guilhermeblanco@gmail.com" 661 | }, 662 | { 663 | "name": "Johannes Schmitt", 664 | "email": "schmittjoh@gmail.com" 665 | } 666 | ], 667 | "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", 668 | "homepage": "http://www.doctrine-project.org", 669 | "keywords": [ 670 | "lexer", 671 | "parser" 672 | ], 673 | "time": "2014-09-09 13:34:57" 674 | }, 675 | { 676 | "name": "filp/whoops", 677 | "version": "2.1.3", 678 | "source": { 679 | "type": "git", 680 | "url": "https://github.com/filp/whoops.git", 681 | "reference": "8828aaa2178e0a19325522e2a45282ff0a14649b" 682 | }, 683 | "dist": { 684 | "type": "zip", 685 | "url": "https://api.github.com/repos/filp/whoops/zipball/8828aaa2178e0a19325522e2a45282ff0a14649b", 686 | "reference": "8828aaa2178e0a19325522e2a45282ff0a14649b", 687 | "shasum": "" 688 | }, 689 | "require": { 690 | "php": ">=5.5.9" 691 | }, 692 | "require-dev": { 693 | "mockery/mockery": "0.9.*", 694 | "phpunit/phpunit": "^4.8 || ^5.0", 695 | "symfony/var-dumper": "~3.0" 696 | }, 697 | "suggest": { 698 | "symfony/var-dumper": "Pretty print complex values better with var-dumper available", 699 | "whoops/soap": "Formats errors as SOAP responses" 700 | }, 701 | "type": "library", 702 | "extra": { 703 | "branch-alias": { 704 | "dev-master": "2.0-dev" 705 | } 706 | }, 707 | "autoload": { 708 | "psr-4": { 709 | "Whoops\\": "src/Whoops/" 710 | } 711 | }, 712 | "notification-url": "https://packagist.org/downloads/", 713 | "license": [ 714 | "MIT" 715 | ], 716 | "authors": [ 717 | { 718 | "name": "Filipe Dobreira", 719 | "homepage": "https://github.com/filp", 720 | "role": "Developer" 721 | } 722 | ], 723 | "description": "php error handling for cool kids", 724 | "homepage": "https://github.com/filp/whoops", 725 | "keywords": [ 726 | "error", 727 | "exception", 728 | "handling", 729 | "library", 730 | "whoops", 731 | "zf2" 732 | ], 733 | "time": "2016-05-06 18:25:35" 734 | }, 735 | { 736 | "name": "nikic/fast-route", 737 | "version": "v1.0.1", 738 | "source": { 739 | "type": "git", 740 | "url": "https://github.com/nikic/FastRoute.git", 741 | "reference": "8ea928195fa9b907f0d6e48312d323c1a13cc2af" 742 | }, 743 | "dist": { 744 | "type": "zip", 745 | "url": "https://api.github.com/repos/nikic/FastRoute/zipball/8ea928195fa9b907f0d6e48312d323c1a13cc2af", 746 | "reference": "8ea928195fa9b907f0d6e48312d323c1a13cc2af", 747 | "shasum": "" 748 | }, 749 | "require": { 750 | "php": ">=5.4.0" 751 | }, 752 | "type": "library", 753 | "autoload": { 754 | "psr-4": { 755 | "FastRoute\\": "src/" 756 | }, 757 | "files": [ 758 | "src/functions.php" 759 | ] 760 | }, 761 | "notification-url": "https://packagist.org/downloads/", 762 | "license": [ 763 | "BSD-3-Clause" 764 | ], 765 | "authors": [ 766 | { 767 | "name": "Nikita Popov", 768 | "email": "nikic@php.net" 769 | } 770 | ], 771 | "description": "Fast request router for PHP", 772 | "keywords": [ 773 | "router", 774 | "routing" 775 | ], 776 | "time": "2016-06-12 19:08:51" 777 | }, 778 | { 779 | "name": "paragonie/random_compat", 780 | "version": "v2.0.2", 781 | "source": { 782 | "type": "git", 783 | "url": "https://github.com/paragonie/random_compat.git", 784 | "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf" 785 | }, 786 | "dist": { 787 | "type": "zip", 788 | "url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf", 789 | "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf", 790 | "shasum": "" 791 | }, 792 | "require": { 793 | "php": ">=5.2.0" 794 | }, 795 | "require-dev": { 796 | "phpunit/phpunit": "4.*|5.*" 797 | }, 798 | "suggest": { 799 | "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." 800 | }, 801 | "type": "library", 802 | "autoload": { 803 | "files": [ 804 | "lib/random.php" 805 | ] 806 | }, 807 | "notification-url": "https://packagist.org/downloads/", 808 | "license": [ 809 | "MIT" 810 | ], 811 | "authors": [ 812 | { 813 | "name": "Paragon Initiative Enterprises", 814 | "email": "security@paragonie.com", 815 | "homepage": "https://paragonie.com" 816 | } 817 | ], 818 | "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", 819 | "keywords": [ 820 | "csprng", 821 | "pseudorandom", 822 | "random" 823 | ], 824 | "time": "2016-04-03 06:00:07" 825 | }, 826 | { 827 | "name": "prooph/common", 828 | "version": "v3.7.1", 829 | "source": { 830 | "type": "git", 831 | "url": "https://github.com/prooph/common.git", 832 | "reference": "468502f8c94c7f01dfac6be2bbcb55ec5f31d44c" 833 | }, 834 | "dist": { 835 | "type": "zip", 836 | "url": "https://api.github.com/repos/prooph/common/zipball/468502f8c94c7f01dfac6be2bbcb55ec5f31d44c", 837 | "reference": "468502f8c94c7f01dfac6be2bbcb55ec5f31d44c", 838 | "shasum": "" 839 | }, 840 | "require": { 841 | "beberlei/assert": "~2.3", 842 | "php": "~5.5|~7.0", 843 | "ramsey/uuid": "~2.8" 844 | }, 845 | "require-dev": { 846 | "fabpot/php-cs-fixer": "1.7.*", 847 | "phpunit/phpunit": "~4.8", 848 | "satooshi/php-coveralls": "^1.0" 849 | }, 850 | "type": "library", 851 | "autoload": { 852 | "psr-4": { 853 | "Prooph\\Common\\": "src" 854 | } 855 | }, 856 | "notification-url": "https://packagist.org/downloads/", 857 | "license": [ 858 | "BSD-3-Clause" 859 | ], 860 | "authors": [ 861 | { 862 | "name": "Sascha-Oliver Prolic", 863 | "email": "saschaprolic@googlemail.com" 864 | }, 865 | { 866 | "name": "Alexander Miertsch", 867 | "email": "contact@prooph.de", 868 | "homepage": "http://www.prooph.de" 869 | } 870 | ], 871 | "description": "Common classes used across prooph packages", 872 | "homepage": "http://getprooph.org/", 873 | "keywords": [ 874 | "common", 875 | "prooph" 876 | ], 877 | "time": "2016-05-14 06:40:38" 878 | }, 879 | { 880 | "name": "prooph/event-sourcing", 881 | "version": "v4.0", 882 | "source": { 883 | "type": "git", 884 | "url": "https://github.com/prooph/event-sourcing.git", 885 | "reference": "159ce90305c5fcba1677af6b152b31ef983c0575" 886 | }, 887 | "dist": { 888 | "type": "zip", 889 | "url": "https://api.github.com/repos/prooph/event-sourcing/zipball/159ce90305c5fcba1677af6b152b31ef983c0575", 890 | "reference": "159ce90305c5fcba1677af6b152b31ef983c0575", 891 | "shasum": "" 892 | }, 893 | "require": { 894 | "beberlei/assert": "~2.3", 895 | "php": "~5.5|~7.0", 896 | "prooph/common": "~3.5", 897 | "ramsey/uuid": "~2.8" 898 | }, 899 | "require-dev": { 900 | "fabpot/php-cs-fixer": "1.7.*", 901 | "phpunit/phpunit": "~4.8", 902 | "prooph/event-store": "dev-develop", 903 | "satooshi/php-coveralls": "dev-master" 904 | }, 905 | "suggest": { 906 | "prooph/event-store": "^6.0 - Use prooph/event-store to persist recorded events in event streams" 907 | }, 908 | "type": "library", 909 | "autoload": { 910 | "psr-4": { 911 | "Prooph\\EventSourcing\\": "src/" 912 | } 913 | }, 914 | "notification-url": "https://packagist.org/downloads/", 915 | "license": [ 916 | "BSD-3-Clause" 917 | ], 918 | "authors": [ 919 | { 920 | "name": "Sascha-Oliver Prolic", 921 | "email": "saschaprolic@googlemail.com" 922 | }, 923 | { 924 | "name": "Alexander Miertsch", 925 | "email": "contact@prooph.de", 926 | "homepage": "http://www.prooph.de" 927 | } 928 | ], 929 | "description": "PHP EventSourcing library", 930 | "homepage": "http://getprooph.org/", 931 | "keywords": [ 932 | "EventSourcing", 933 | "ddd", 934 | "prooph" 935 | ], 936 | "time": "2015-11-22 22:43:03" 937 | }, 938 | { 939 | "name": "prooph/event-store", 940 | "version": "v6.4.0", 941 | "source": { 942 | "type": "git", 943 | "url": "https://github.com/prooph/event-store.git", 944 | "reference": "63f8dca3e7ebff44cf02a02c97d5a3cc980d2633" 945 | }, 946 | "dist": { 947 | "type": "zip", 948 | "url": "https://api.github.com/repos/prooph/event-store/zipball/63f8dca3e7ebff44cf02a02c97d5a3cc980d2633", 949 | "reference": "63f8dca3e7ebff44cf02a02c97d5a3cc980d2633", 950 | "shasum": "" 951 | }, 952 | "require": { 953 | "beberlei/assert": "~2.3", 954 | "php": "~5.5|~7.0", 955 | "prooph/common": "~3.7" 956 | }, 957 | "conflict": { 958 | "sandrokeil/interop-config": "<1.0" 959 | }, 960 | "require-dev": { 961 | "container-interop/container-interop": "^1.1", 962 | "friendsofphp/php-cs-fixer": "^1.12.0", 963 | "malukenho/docheader": "^0.1.3", 964 | "phpunit/phpunit": "~4.8", 965 | "ramsey/uuid": "~2.8", 966 | "sandrokeil/interop-config": "^1.0", 967 | "satooshi/php-coveralls": "^1.0", 968 | "tobiju/bookdown-bootswatch-templates": "^1.0", 969 | "zendframework/zend-servicemanager": "~2.6" 970 | }, 971 | "suggest": { 972 | "container-interop/container-interop": "For usage of provided factories", 973 | "prooph/event-sourcing": "Basic functionality for event sourced aggregates", 974 | "prooph/event-store-doctrine-adapter": "For usage with doctrine dbal as event store adapter", 975 | "prooph/event-store-flywheel-adapter": "For usage with flywheel as event store adapter", 976 | "prooph/event-store-mongodb-adapter": "For usage with mongodb as event store adapter", 977 | "prooph/service-bus": "Message bus facade to connect the event store with messaging systems", 978 | "prooph/snapshot-doctrine-adapter": "For usage with doctrine dbal as snapshot adapter", 979 | "prooph/snapshot-memcached-adapter": "For usage with memcached as snapshot adapter", 980 | "prooph/snapshot-mongodb-adapter": "For usage with mongodb as snapshot adapter", 981 | "sandrokeil/interop-config": "For usage of provided factories" 982 | }, 983 | "type": "library", 984 | "autoload": { 985 | "psr-4": { 986 | "Prooph\\EventStore\\": "src/" 987 | } 988 | }, 989 | "notification-url": "https://packagist.org/downloads/", 990 | "license": [ 991 | "BSD-3-Clause" 992 | ], 993 | "authors": [ 994 | { 995 | "name": "Sascha-Oliver Prolic", 996 | "email": "saschaprolic@googlemail.com" 997 | }, 998 | { 999 | "name": "Alexander Miertsch", 1000 | "email": "contact@prooph.de", 1001 | "homepage": "http://www.prooph.de" 1002 | } 1003 | ], 1004 | "description": "PHP EventStore Implementation", 1005 | "homepage": "http://getprooph.org/", 1006 | "keywords": [ 1007 | "EventSourcing", 1008 | "EventStore", 1009 | "ddd", 1010 | "prooph" 1011 | ], 1012 | "time": "2016-09-05 09:15:14" 1013 | }, 1014 | { 1015 | "name": "prooph/event-store-bus-bridge", 1016 | "version": "v2.0", 1017 | "source": { 1018 | "type": "git", 1019 | "url": "https://github.com/prooph/event-store-bus-bridge.git", 1020 | "reference": "ca46e6f7417d3ce6a24911fcef94513fc808470d" 1021 | }, 1022 | "dist": { 1023 | "type": "zip", 1024 | "url": "https://api.github.com/repos/prooph/event-store-bus-bridge/zipball/ca46e6f7417d3ce6a24911fcef94513fc808470d", 1025 | "reference": "ca46e6f7417d3ce6a24911fcef94513fc808470d", 1026 | "shasum": "" 1027 | }, 1028 | "require": { 1029 | "php": "~5.5|~7.0", 1030 | "prooph/event-store": "^6.0", 1031 | "prooph/service-bus": "^5.0" 1032 | }, 1033 | "require-dev": { 1034 | "container-interop/container-interop": "^1.1", 1035 | "fabpot/php-cs-fixer": "1.7.*", 1036 | "phpunit/phpunit": "~4.8", 1037 | "satooshi/php-coveralls": "dev-master", 1038 | "tobiju/bookdown-bootswatch-templates": "^0.2.0" 1039 | }, 1040 | "type": "library", 1041 | "autoload": { 1042 | "psr-4": { 1043 | "Prooph\\EventStoreBusBridge\\": "src/" 1044 | } 1045 | }, 1046 | "notification-url": "https://packagist.org/downloads/", 1047 | "license": [ 1048 | "BSD-3-Clause" 1049 | ], 1050 | "authors": [ 1051 | { 1052 | "name": "Sascha-Oliver Prolic", 1053 | "email": "saschaprolic@googlemail.com" 1054 | }, 1055 | { 1056 | "name": "Alexander Miertsch", 1057 | "email": "contact@prooph.de", 1058 | "homepage": "http://www.codeliner.ws/" 1059 | } 1060 | ], 1061 | "description": "Marry CQRS with Event Sourcing", 1062 | "homepage": "http://getprooph.org/", 1063 | "keywords": [ 1064 | "EventSourcing", 1065 | "cqrs", 1066 | "prooph" 1067 | ], 1068 | "time": "2015-11-22 22:54:53" 1069 | }, 1070 | { 1071 | "name": "prooph/event-store-doctrine-adapter", 1072 | "version": "v3.2.1", 1073 | "source": { 1074 | "type": "git", 1075 | "url": "https://github.com/prooph/event-store-doctrine-adapter.git", 1076 | "reference": "8e62f0d4dfcb09735c942c59fb9671a7ce57168b" 1077 | }, 1078 | "dist": { 1079 | "type": "zip", 1080 | "url": "https://api.github.com/repos/prooph/event-store-doctrine-adapter/zipball/8e62f0d4dfcb09735c942c59fb9671a7ce57168b", 1081 | "reference": "8e62f0d4dfcb09735c942c59fb9671a7ce57168b", 1082 | "shasum": "" 1083 | }, 1084 | "require": { 1085 | "beberlei/assert": "^2.3", 1086 | "doctrine/dbal": "^2.5", 1087 | "php": "~5.5|~7.0", 1088 | "prooph/common": "^3.7", 1089 | "prooph/event-store": "^6.3" 1090 | }, 1091 | "conflict": { 1092 | "sandrokeil/interop-config": "<1.0" 1093 | }, 1094 | "require-dev": { 1095 | "container-interop/container-interop": "^1.1", 1096 | "fabpot/php-cs-fixer": "1.7.*", 1097 | "phpunit/phpunit": "^4.8", 1098 | "sandrokeil/interop-config": "^1.0", 1099 | "satooshi/php-coveralls": "^1.0", 1100 | "sebastian/comparator": "^1.2" 1101 | }, 1102 | "suggest": { 1103 | "container-interop/container-interop": "For usage of provided factories", 1104 | "sandrokeil/interop-config": "For usage of provided factories" 1105 | }, 1106 | "type": "library", 1107 | "autoload": { 1108 | "psr-4": { 1109 | "Prooph\\EventStore\\Adapter\\Doctrine\\": "src/" 1110 | } 1111 | }, 1112 | "notification-url": "https://packagist.org/downloads/", 1113 | "license": [ 1114 | "BSD-3-Clause" 1115 | ], 1116 | "authors": [ 1117 | { 1118 | "name": "Jan Sorgalla", 1119 | "email": "jan.sorgalla@dotsunited.de", 1120 | "homepage": "http://dotsunited.de" 1121 | }, 1122 | { 1123 | "name": "Alexander Miertsch", 1124 | "email": "contact@prooph.de", 1125 | "homepage": "http://www.prooph.de/" 1126 | }, 1127 | { 1128 | "name": "Sascha-Oliver Prolic", 1129 | "email": "saschaprolic@googlemail.com" 1130 | } 1131 | ], 1132 | "description": "Doctrine Adapter for ProophEventStore", 1133 | "homepage": "http://getprooph.org/", 1134 | "time": "2016-06-28 19:49:20" 1135 | }, 1136 | { 1137 | "name": "prooph/psb-bernard-producer", 1138 | "version": "v2.0", 1139 | "source": { 1140 | "type": "git", 1141 | "url": "https://github.com/prooph/psb-bernard-producer.git", 1142 | "reference": "69f7e69e10405376d3dfa65a2580d34e7d672a89" 1143 | }, 1144 | "dist": { 1145 | "type": "zip", 1146 | "url": "https://api.github.com/repos/prooph/psb-bernard-producer/zipball/69f7e69e10405376d3dfa65a2580d34e7d672a89", 1147 | "reference": "69f7e69e10405376d3dfa65a2580d34e7d672a89", 1148 | "shasum": "" 1149 | }, 1150 | "require": { 1151 | "bernard/bernard": "1.0.*@dev", 1152 | "php": "~5.5|~7.0", 1153 | "prooph/common": "^3.5" 1154 | }, 1155 | "conflict": { 1156 | "prooph/psb-bernard-dispatcher": "*" 1157 | }, 1158 | "require-dev": { 1159 | "doctrine/dbal": "~2.4", 1160 | "fabpot/php-cs-fixer": "1.7.*", 1161 | "phpunit/phpunit": "~4.7", 1162 | "prooph/service-bus": "dev-master", 1163 | "satooshi/php-coveralls": "dev-master" 1164 | }, 1165 | "type": "library", 1166 | "autoload": { 1167 | "psr-4": { 1168 | "Prooph\\ServiceBus\\Message\\Bernard\\": "src/" 1169 | } 1170 | }, 1171 | "notification-url": "https://packagist.org/downloads/", 1172 | "license": [ 1173 | "BSD-3-Clause" 1174 | ], 1175 | "authors": [ 1176 | { 1177 | "name": "Sascha-Oliver Prolic", 1178 | "email": "saschaprolic@googlemail.com" 1179 | }, 1180 | { 1181 | "name": "Alexander Miertsch", 1182 | "email": "contact@prooph.de", 1183 | "homepage": "http://www.prooph.de" 1184 | }, 1185 | { 1186 | "name": "Guy Radford", 1187 | "email": "guyr@gfrs.co.uk" 1188 | } 1189 | ], 1190 | "description": "Bernard Message Producer for Prooph Service Bus", 1191 | "homepage": "http://getprooph.org/", 1192 | "keywords": [ 1193 | "bernard", 1194 | "cqrs", 1195 | "messaging", 1196 | "prooph" 1197 | ], 1198 | "time": "2016-08-22 20:00:38" 1199 | }, 1200 | { 1201 | "name": "prooph/service-bus", 1202 | "version": "v5.2.0", 1203 | "source": { 1204 | "type": "git", 1205 | "url": "https://github.com/prooph/service-bus.git", 1206 | "reference": "f1add20508c9a6b979f6003059133b9b3959c2e8" 1207 | }, 1208 | "dist": { 1209 | "type": "zip", 1210 | "url": "https://api.github.com/repos/prooph/service-bus/zipball/f1add20508c9a6b979f6003059133b9b3959c2e8", 1211 | "reference": "f1add20508c9a6b979f6003059133b9b3959c2e8", 1212 | "shasum": "" 1213 | }, 1214 | "require": { 1215 | "beberlei/assert": "^2.4", 1216 | "php": "~5.5 || ~7.0", 1217 | "prooph/common": "^3.7" 1218 | }, 1219 | "conflict": { 1220 | "sandrokeil/interop-config": "<1.0" 1221 | }, 1222 | "require-dev": { 1223 | "container-interop/container-interop": "^1.1", 1224 | "fabpot/php-cs-fixer": "^1.7", 1225 | "malukenho/docheader": "^0.1.2", 1226 | "phpunit/phpunit": "^4.8.23", 1227 | "react/promise": "^2.2.2", 1228 | "sandrokeil/interop-config": "^1.0", 1229 | "satooshi/php-coveralls": "^1.0", 1230 | "tobiju/bookdown-bootswatch-templates": "^1.0" 1231 | }, 1232 | "suggest": { 1233 | "container-interop/container-interop": "For usage of provided factories", 1234 | "prooph/event-store": "Let the EventBus dispatch persisted DomainEvents", 1235 | "prooph/service-bus-zfc-rbac-bridge": "Use ZfcRbac as authorization service for route and finalize guard", 1236 | "react/promise": "^2.2.2 for usage with provided QueryBus", 1237 | "sandrokeil/interop-config": "For usage of provided factories", 1238 | "zendframework/zend-servicemanager": "Use Zend ServiceManager to lazy load your handlers and listeners" 1239 | }, 1240 | "type": "library", 1241 | "autoload": { 1242 | "psr-4": { 1243 | "Prooph\\ServiceBus\\": "src/" 1244 | } 1245 | }, 1246 | "notification-url": "https://packagist.org/downloads/", 1247 | "license": [ 1248 | "BSD-3-Clause" 1249 | ], 1250 | "authors": [ 1251 | { 1252 | "name": "Sascha-Oliver Prolic", 1253 | "email": "saschaprolic@googlemail.com" 1254 | }, 1255 | { 1256 | "name": "Alexander Miertsch", 1257 | "email": "contact@prooph.de", 1258 | "homepage": "http://www.prooph.de" 1259 | } 1260 | ], 1261 | "description": "PHP Enterprise Service Bus Implementation supporting CQRS and DDD", 1262 | "homepage": "http://getprooph.org/", 1263 | "keywords": [ 1264 | "cqrs", 1265 | "ddd", 1266 | "messaging", 1267 | "prooph" 1268 | ], 1269 | "time": "2016-09-02 09:07:26" 1270 | }, 1271 | { 1272 | "name": "psr/http-message", 1273 | "version": "1.0.1", 1274 | "source": { 1275 | "type": "git", 1276 | "url": "https://github.com/php-fig/http-message.git", 1277 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 1278 | }, 1279 | "dist": { 1280 | "type": "zip", 1281 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", 1282 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 1283 | "shasum": "" 1284 | }, 1285 | "require": { 1286 | "php": ">=5.3.0" 1287 | }, 1288 | "type": "library", 1289 | "extra": { 1290 | "branch-alias": { 1291 | "dev-master": "1.0.x-dev" 1292 | } 1293 | }, 1294 | "autoload": { 1295 | "psr-4": { 1296 | "Psr\\Http\\Message\\": "src/" 1297 | } 1298 | }, 1299 | "notification-url": "https://packagist.org/downloads/", 1300 | "license": [ 1301 | "MIT" 1302 | ], 1303 | "authors": [ 1304 | { 1305 | "name": "PHP-FIG", 1306 | "homepage": "http://www.php-fig.org/" 1307 | } 1308 | ], 1309 | "description": "Common interface for HTTP messages", 1310 | "homepage": "https://github.com/php-fig/http-message", 1311 | "keywords": [ 1312 | "http", 1313 | "http-message", 1314 | "psr", 1315 | "psr-7", 1316 | "request", 1317 | "response" 1318 | ], 1319 | "time": "2016-08-06 14:39:51" 1320 | }, 1321 | { 1322 | "name": "ramsey/uuid", 1323 | "version": "2.9.0", 1324 | "source": { 1325 | "type": "git", 1326 | "url": "https://github.com/ramsey/uuid.git", 1327 | "reference": "b2ef4dd9584268d73f92f752a62bc24cd534dc9a" 1328 | }, 1329 | "dist": { 1330 | "type": "zip", 1331 | "url": "https://api.github.com/repos/ramsey/uuid/zipball/b2ef4dd9584268d73f92f752a62bc24cd534dc9a", 1332 | "reference": "b2ef4dd9584268d73f92f752a62bc24cd534dc9a", 1333 | "shasum": "" 1334 | }, 1335 | "require": { 1336 | "paragonie/random_compat": "^1.0|^2.0", 1337 | "php": ">=5.3.3" 1338 | }, 1339 | "replace": { 1340 | "rhumsaa/uuid": "self.version" 1341 | }, 1342 | "require-dev": { 1343 | "doctrine/dbal": ">=2.3", 1344 | "jakub-onderka/php-parallel-lint": "^0.9.0", 1345 | "moontoast/math": "~1.1", 1346 | "phpunit/phpunit": "~4.1|~5.0", 1347 | "satooshi/php-coveralls": "~0.6", 1348 | "squizlabs/php_codesniffer": "^2.3", 1349 | "symfony/console": "~2.3|~3.0" 1350 | }, 1351 | "suggest": { 1352 | "doctrine/dbal": "Allow the use of a UUID as doctrine field type.", 1353 | "moontoast/math": "Support for converting UUID to 128-bit integer (in string form).", 1354 | "symfony/console": "Support for use of the bin/uuid command line tool." 1355 | }, 1356 | "bin": [ 1357 | "bin/uuid" 1358 | ], 1359 | "type": "library", 1360 | "autoload": { 1361 | "psr-4": { 1362 | "Rhumsaa\\Uuid\\": "src/" 1363 | } 1364 | }, 1365 | "notification-url": "https://packagist.org/downloads/", 1366 | "license": [ 1367 | "MIT" 1368 | ], 1369 | "authors": [ 1370 | { 1371 | "name": "Marijn Huizendveld", 1372 | "email": "marijn.huizendveld@gmail.com" 1373 | }, 1374 | { 1375 | "name": "Ben Ramsey", 1376 | "homepage": "http://benramsey.com" 1377 | } 1378 | ], 1379 | "description": "A PHP 5.3+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", 1380 | "homepage": "https://github.com/ramsey/uuid", 1381 | "keywords": [ 1382 | "guid", 1383 | "identifier", 1384 | "uuid" 1385 | ], 1386 | "time": "2016-03-22 18:20:19" 1387 | }, 1388 | { 1389 | "name": "symfony/event-dispatcher", 1390 | "version": "v3.1.4", 1391 | "source": { 1392 | "type": "git", 1393 | "url": "https://github.com/symfony/event-dispatcher.git", 1394 | "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5" 1395 | }, 1396 | "dist": { 1397 | "type": "zip", 1398 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c0c00c80b3a69132c4e55c3e7db32b4a387615e5", 1399 | "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5", 1400 | "shasum": "" 1401 | }, 1402 | "require": { 1403 | "php": ">=5.5.9" 1404 | }, 1405 | "require-dev": { 1406 | "psr/log": "~1.0", 1407 | "symfony/config": "~2.8|~3.0", 1408 | "symfony/dependency-injection": "~2.8|~3.0", 1409 | "symfony/expression-language": "~2.8|~3.0", 1410 | "symfony/stopwatch": "~2.8|~3.0" 1411 | }, 1412 | "suggest": { 1413 | "symfony/dependency-injection": "", 1414 | "symfony/http-kernel": "" 1415 | }, 1416 | "type": "library", 1417 | "extra": { 1418 | "branch-alias": { 1419 | "dev-master": "3.1-dev" 1420 | } 1421 | }, 1422 | "autoload": { 1423 | "psr-4": { 1424 | "Symfony\\Component\\EventDispatcher\\": "" 1425 | }, 1426 | "exclude-from-classmap": [ 1427 | "/Tests/" 1428 | ] 1429 | }, 1430 | "notification-url": "https://packagist.org/downloads/", 1431 | "license": [ 1432 | "MIT" 1433 | ], 1434 | "authors": [ 1435 | { 1436 | "name": "Fabien Potencier", 1437 | "email": "fabien@symfony.com" 1438 | }, 1439 | { 1440 | "name": "Symfony Community", 1441 | "homepage": "https://symfony.com/contributors" 1442 | } 1443 | ], 1444 | "description": "Symfony EventDispatcher Component", 1445 | "homepage": "https://symfony.com", 1446 | "time": "2016-07-19 10:45:57" 1447 | }, 1448 | { 1449 | "name": "symfony/serializer", 1450 | "version": "v3.1.4", 1451 | "source": { 1452 | "type": "git", 1453 | "url": "https://github.com/symfony/serializer.git", 1454 | "reference": "81674b4a42507b6f3ba3a0661b35bfad8d25f841" 1455 | }, 1456 | "dist": { 1457 | "type": "zip", 1458 | "url": "https://api.github.com/repos/symfony/serializer/zipball/81674b4a42507b6f3ba3a0661b35bfad8d25f841", 1459 | "reference": "81674b4a42507b6f3ba3a0661b35bfad8d25f841", 1460 | "shasum": "" 1461 | }, 1462 | "require": { 1463 | "php": ">=5.5.9" 1464 | }, 1465 | "conflict": { 1466 | "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4" 1467 | }, 1468 | "require-dev": { 1469 | "doctrine/annotations": "~1.0", 1470 | "doctrine/cache": "~1.0", 1471 | "phpdocumentor/reflection-docblock": "~3.0", 1472 | "symfony/cache": "~3.1", 1473 | "symfony/config": "~2.8|~3.0", 1474 | "symfony/http-foundation": "~2.8|~3.0", 1475 | "symfony/property-access": "~2.8|~3.0", 1476 | "symfony/property-info": "~3.1", 1477 | "symfony/yaml": "~2.8|~3.0" 1478 | }, 1479 | "suggest": { 1480 | "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", 1481 | "doctrine/cache": "For using the default cached annotation reader and metadata cache.", 1482 | "psr/cache-implementation": "For using the metadata cache.", 1483 | "symfony/config": "For using the XML mapping loader.", 1484 | "symfony/http-foundation": "To use the DataUriNormalizer.", 1485 | "symfony/property-access": "For using the ObjectNormalizer.", 1486 | "symfony/property-info": "To deserialize relations.", 1487 | "symfony/yaml": "For using the default YAML mapping loader." 1488 | }, 1489 | "type": "library", 1490 | "extra": { 1491 | "branch-alias": { 1492 | "dev-master": "3.1-dev" 1493 | } 1494 | }, 1495 | "autoload": { 1496 | "psr-4": { 1497 | "Symfony\\Component\\Serializer\\": "" 1498 | }, 1499 | "exclude-from-classmap": [ 1500 | "/Tests/" 1501 | ] 1502 | }, 1503 | "notification-url": "https://packagist.org/downloads/", 1504 | "license": [ 1505 | "MIT" 1506 | ], 1507 | "authors": [ 1508 | { 1509 | "name": "Fabien Potencier", 1510 | "email": "fabien@symfony.com" 1511 | }, 1512 | { 1513 | "name": "Symfony Community", 1514 | "homepage": "https://symfony.com/contributors" 1515 | } 1516 | ], 1517 | "description": "Symfony Serializer Component", 1518 | "homepage": "https://symfony.com", 1519 | "time": "2016-08-19 15:12:52" 1520 | }, 1521 | { 1522 | "name": "zendframework/zend-diactoros", 1523 | "version": "1.3.6", 1524 | "source": { 1525 | "type": "git", 1526 | "url": "https://github.com/zendframework/zend-diactoros.git", 1527 | "reference": "a60da179c37f2c4e44ef734d0b92824a58943f7f" 1528 | }, 1529 | "dist": { 1530 | "type": "zip", 1531 | "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/a60da179c37f2c4e44ef734d0b92824a58943f7f", 1532 | "reference": "a60da179c37f2c4e44ef734d0b92824a58943f7f", 1533 | "shasum": "" 1534 | }, 1535 | "require": { 1536 | "php": "^5.4 || ^7.0", 1537 | "psr/http-message": "~1.0" 1538 | }, 1539 | "provide": { 1540 | "psr/http-message-implementation": "~1.0.0" 1541 | }, 1542 | "require-dev": { 1543 | "phpunit/phpunit": "^4.6 || ^5.5", 1544 | "squizlabs/php_codesniffer": "^2.3.1" 1545 | }, 1546 | "type": "library", 1547 | "extra": { 1548 | "branch-alias": { 1549 | "dev-master": "1.3-dev", 1550 | "dev-develop": "1.4-dev" 1551 | } 1552 | }, 1553 | "autoload": { 1554 | "psr-4": { 1555 | "Zend\\Diactoros\\": "src/" 1556 | } 1557 | }, 1558 | "notification-url": "https://packagist.org/downloads/", 1559 | "license": [ 1560 | "BSD-2-Clause" 1561 | ], 1562 | "description": "PSR HTTP Message implementations", 1563 | "homepage": "https://github.com/zendframework/zend-diactoros", 1564 | "keywords": [ 1565 | "http", 1566 | "psr", 1567 | "psr-7" 1568 | ], 1569 | "time": "2016-09-07 17:57:29" 1570 | }, 1571 | { 1572 | "name": "zendframework/zend-escaper", 1573 | "version": "2.5.2", 1574 | "source": { 1575 | "type": "git", 1576 | "url": "https://github.com/zendframework/zend-escaper.git", 1577 | "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e" 1578 | }, 1579 | "dist": { 1580 | "type": "zip", 1581 | "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/2dcd14b61a72d8b8e27d579c6344e12c26141d4e", 1582 | "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e", 1583 | "shasum": "" 1584 | }, 1585 | "require": { 1586 | "php": ">=5.5" 1587 | }, 1588 | "require-dev": { 1589 | "fabpot/php-cs-fixer": "1.7.*", 1590 | "phpunit/phpunit": "~4.0" 1591 | }, 1592 | "type": "library", 1593 | "extra": { 1594 | "branch-alias": { 1595 | "dev-master": "2.5-dev", 1596 | "dev-develop": "2.6-dev" 1597 | } 1598 | }, 1599 | "autoload": { 1600 | "psr-4": { 1601 | "Zend\\Escaper\\": "src/" 1602 | } 1603 | }, 1604 | "notification-url": "https://packagist.org/downloads/", 1605 | "license": [ 1606 | "BSD-3-Clause" 1607 | ], 1608 | "homepage": "https://github.com/zendframework/zend-escaper", 1609 | "keywords": [ 1610 | "escaper", 1611 | "zf2" 1612 | ], 1613 | "time": "2016-06-30 19:48:38" 1614 | }, 1615 | { 1616 | "name": "zendframework/zend-expressive", 1617 | "version": "1.0.0", 1618 | "source": { 1619 | "type": "git", 1620 | "url": "https://github.com/zendframework/zend-expressive.git", 1621 | "reference": "4e6b1821e116425c76a515cae9b78141f17b2e1a" 1622 | }, 1623 | "dist": { 1624 | "type": "zip", 1625 | "url": "https://api.github.com/repos/zendframework/zend-expressive/zipball/4e6b1821e116425c76a515cae9b78141f17b2e1a", 1626 | "reference": "4e6b1821e116425c76a515cae9b78141f17b2e1a", 1627 | "shasum": "" 1628 | }, 1629 | "require": { 1630 | "container-interop/container-interop": "^1.1", 1631 | "php": "^5.5 || ^7.0", 1632 | "psr/http-message": "^1.0", 1633 | "zendframework/zend-diactoros": "^1.1", 1634 | "zendframework/zend-expressive-router": "^1.1", 1635 | "zendframework/zend-expressive-template": "^1.0.1", 1636 | "zendframework/zend-stratigility": "^1.1" 1637 | }, 1638 | "require-dev": { 1639 | "filp/whoops": "^1.1", 1640 | "phpunit/phpunit": "^4.7", 1641 | "squizlabs/php_codesniffer": "^2.3", 1642 | "zendframework/zend-expressive-aurarouter": "^1.0", 1643 | "zendframework/zend-expressive-fastroute": "^1.0", 1644 | "zendframework/zend-expressive-zendrouter": "^1.0", 1645 | "zendframework/zend-servicemanager": "^2.6" 1646 | }, 1647 | "suggest": { 1648 | "aura/di": "3.0.*@beta to make use of Aura.Di dependency injection container", 1649 | "filp/whoops": "^1.1 to use the Whoops error handler", 1650 | "xtreamwayz/pimple-container-interop": "^1.0 to use Pimple for dependency injection", 1651 | "zendframework/zend-expressive-aurarouter": "^1.0 to use the Aura.Router routing adapter", 1652 | "zendframework/zend-expressive-fastroute": "^1.0 to use the FastRoute routing adapter", 1653 | "zendframework/zend-expressive-helpers": "^1.0 for its UrlHelper, ServerUrlHelper, and BodyParseMiddleware", 1654 | "zendframework/zend-expressive-platesrenderer": "^1.0 to use the Plates template renderer", 1655 | "zendframework/zend-expressive-twigrenderer": "^1.0 to use the Twig template renderer", 1656 | "zendframework/zend-expressive-zendrouter": "^1.0 to use the zend-mvc routing adapter", 1657 | "zendframework/zend-expressive-zendviewrenderer": "^1.0 to use the zend-view PhpRenderer template renderer", 1658 | "zendframework/zend-servicemanager": "^2.5 to use zend-servicemanager for dependency injection" 1659 | }, 1660 | "type": "library", 1661 | "extra": { 1662 | "branch-alias": { 1663 | "dev-master": "1.0-dev", 1664 | "dev-develop": "1.1-dev" 1665 | } 1666 | }, 1667 | "autoload": { 1668 | "psr-4": { 1669 | "Zend\\Expressive\\": "src/" 1670 | } 1671 | }, 1672 | "notification-url": "https://packagist.org/downloads/", 1673 | "license": [ 1674 | "BSD-3-Clause" 1675 | ], 1676 | "description": "PSR-7 Middleware Microframework based on Stratigility", 1677 | "keywords": [ 1678 | "http", 1679 | "middleware", 1680 | "psr", 1681 | "psr-7" 1682 | ], 1683 | "time": "2016-01-28 15:49:52" 1684 | }, 1685 | { 1686 | "name": "zendframework/zend-expressive-fastroute", 1687 | "version": "1.2.0", 1688 | "source": { 1689 | "type": "git", 1690 | "url": "https://github.com/zendframework/zend-expressive-fastroute.git", 1691 | "reference": "2d08527ee8b4ac8709a9dae626f868eaaa1d84e6" 1692 | }, 1693 | "dist": { 1694 | "type": "zip", 1695 | "url": "https://api.github.com/repos/zendframework/zend-expressive-fastroute/zipball/2d08527ee8b4ac8709a9dae626f868eaaa1d84e6", 1696 | "reference": "2d08527ee8b4ac8709a9dae626f868eaaa1d84e6", 1697 | "shasum": "" 1698 | }, 1699 | "require": { 1700 | "nikic/fast-route": "^1.0.0", 1701 | "php": "^5.5 || ^7.0", 1702 | "psr/http-message": "^1.0", 1703 | "zendframework/zend-expressive-router": "^1.0" 1704 | }, 1705 | "require-dev": { 1706 | "phpunit/phpunit": "^4.7", 1707 | "squizlabs/php_codesniffer": "^2.3" 1708 | }, 1709 | "type": "library", 1710 | "extra": { 1711 | "branch-alias": { 1712 | "dev-master": "1.1-dev", 1713 | "dev-develop": "1.2-dev" 1714 | } 1715 | }, 1716 | "autoload": { 1717 | "psr-4": { 1718 | "Zend\\Expressive\\Router\\": "src/" 1719 | } 1720 | }, 1721 | "notification-url": "https://packagist.org/downloads/", 1722 | "license": [ 1723 | "BSD-3-Clause" 1724 | ], 1725 | "description": "FastRoute integration for Expressive", 1726 | "keywords": [ 1727 | "FastRoute", 1728 | "expressive", 1729 | "http", 1730 | "middleware", 1731 | "psr", 1732 | "psr-7" 1733 | ], 1734 | "time": "2016-06-16 13:37:19" 1735 | }, 1736 | { 1737 | "name": "zendframework/zend-expressive-router", 1738 | "version": "1.2.0", 1739 | "source": { 1740 | "type": "git", 1741 | "url": "https://github.com/zendframework/zend-expressive-router.git", 1742 | "reference": "ec11c758e067c3eef579cb51dcabfcbf5de2ec03" 1743 | }, 1744 | "dist": { 1745 | "type": "zip", 1746 | "url": "https://api.github.com/repos/zendframework/zend-expressive-router/zipball/ec11c758e067c3eef579cb51dcabfcbf5de2ec03", 1747 | "reference": "ec11c758e067c3eef579cb51dcabfcbf5de2ec03", 1748 | "shasum": "" 1749 | }, 1750 | "require": { 1751 | "php": "^5.5 || ^7.0", 1752 | "psr/http-message": "^1.0" 1753 | }, 1754 | "require-dev": { 1755 | "phpunit/phpunit": "^4.7", 1756 | "squizlabs/php_codesniffer": "^2.3" 1757 | }, 1758 | "suggest": { 1759 | "zendframework/zend-expressive-aurarouter": "^0.1 to use the Aura.Router routing adapter", 1760 | "zendframework/zend-expressive-fastroute": "^0.1 to use the FastRoute routing adapter", 1761 | "zendframework/zend-expressive-zendrouter": "^0.1 to use the zend-mvc routing adapter" 1762 | }, 1763 | "type": "library", 1764 | "extra": { 1765 | "branch-alias": { 1766 | "dev-master": "1.2-dev", 1767 | "dev-develop": "1.3-dev" 1768 | } 1769 | }, 1770 | "autoload": { 1771 | "psr-4": { 1772 | "Zend\\Expressive\\Router\\": "src/" 1773 | } 1774 | }, 1775 | "notification-url": "https://packagist.org/downloads/", 1776 | "license": [ 1777 | "BSD-3-Clause" 1778 | ], 1779 | "description": "Router subcomponent for Expressive", 1780 | "keywords": [ 1781 | "expressive", 1782 | "http", 1783 | "middleware", 1784 | "psr", 1785 | "psr-7" 1786 | ], 1787 | "time": "2016-01-18 20:10:33" 1788 | }, 1789 | { 1790 | "name": "zendframework/zend-expressive-template", 1791 | "version": "1.0.3", 1792 | "source": { 1793 | "type": "git", 1794 | "url": "https://github.com/zendframework/zend-expressive-template.git", 1795 | "reference": "2aac4050ebcf9a2c883dc23cf74671da02a66a7b" 1796 | }, 1797 | "dist": { 1798 | "type": "zip", 1799 | "url": "https://api.github.com/repos/zendframework/zend-expressive-template/zipball/2aac4050ebcf9a2c883dc23cf74671da02a66a7b", 1800 | "reference": "2aac4050ebcf9a2c883dc23cf74671da02a66a7b", 1801 | "shasum": "" 1802 | }, 1803 | "require": { 1804 | "php": ">=5.5" 1805 | }, 1806 | "require-dev": { 1807 | "phpunit/phpunit": "^4.7", 1808 | "squizlabs/php_codesniffer": "^2.3" 1809 | }, 1810 | "suggest": { 1811 | "zendframework/zend-expressive-platesrenderer": "^0.1 to use the Plates template renderer", 1812 | "zendframework/zend-expressive-twigrenderer": "^0.1 to use the Twig template renderer", 1813 | "zendframework/zend-expressive-zendviewrenderer": "^0.1 to use the zend-view PhpRenderer template renderer" 1814 | }, 1815 | "type": "library", 1816 | "extra": { 1817 | "branch-alias": { 1818 | "dev-master": "1.0-dev", 1819 | "dev-develop": "1.1-dev" 1820 | } 1821 | }, 1822 | "autoload": { 1823 | "psr-4": { 1824 | "Zend\\Expressive\\Template\\": "src/" 1825 | } 1826 | }, 1827 | "notification-url": "https://packagist.org/downloads/", 1828 | "license": [ 1829 | "BSD-3-Clause" 1830 | ], 1831 | "description": "Template subcomponent for Expressive", 1832 | "keywords": [ 1833 | "expressive", 1834 | "template" 1835 | ], 1836 | "time": "2016-01-28 15:44:23" 1837 | }, 1838 | { 1839 | "name": "zendframework/zend-servicemanager", 1840 | "version": "3.1.1", 1841 | "source": { 1842 | "type": "git", 1843 | "url": "https://github.com/zendframework/zend-servicemanager.git", 1844 | "reference": "f701b0d322741b0c8d8ca1288f249a49438029cd" 1845 | }, 1846 | "dist": { 1847 | "type": "zip", 1848 | "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/f701b0d322741b0c8d8ca1288f249a49438029cd", 1849 | "reference": "f701b0d322741b0c8d8ca1288f249a49438029cd", 1850 | "shasum": "" 1851 | }, 1852 | "require": { 1853 | "container-interop/container-interop": "~1.0", 1854 | "php": "^5.5 || ^7.0" 1855 | }, 1856 | "provide": { 1857 | "container-interop/container-interop-implementation": "^1.1" 1858 | }, 1859 | "require-dev": { 1860 | "ocramius/proxy-manager": "^1.0 || ^2.0", 1861 | "phpbench/phpbench": "^0.10.0", 1862 | "phpunit/phpunit": "^4.6 || ^5.2.10", 1863 | "squizlabs/php_codesniffer": "^2.5.1" 1864 | }, 1865 | "suggest": { 1866 | "ocramius/proxy-manager": "ProxyManager 1.* to handle lazy initialization of services", 1867 | "zendframework/zend-stdlib": "zend-stdlib ^2.5 if you wish to use the MergeReplaceKey or MergeRemoveKey features in Config instances" 1868 | }, 1869 | "type": "library", 1870 | "extra": { 1871 | "branch-alias": { 1872 | "dev-master": "3.1-dev", 1873 | "dev-develop": "3.2-dev" 1874 | } 1875 | }, 1876 | "autoload": { 1877 | "psr-4": { 1878 | "Zend\\ServiceManager\\": "src/" 1879 | } 1880 | }, 1881 | "notification-url": "https://packagist.org/downloads/", 1882 | "license": [ 1883 | "BSD-3-Clause" 1884 | ], 1885 | "homepage": "https://github.com/zendframework/zend-servicemanager", 1886 | "keywords": [ 1887 | "service-manager", 1888 | "servicemanager", 1889 | "zf" 1890 | ], 1891 | "time": "2016-07-15 14:59:51" 1892 | }, 1893 | { 1894 | "name": "zendframework/zend-stratigility", 1895 | "version": "1.2.1", 1896 | "source": { 1897 | "type": "git", 1898 | "url": "https://github.com/zendframework/zend-stratigility.git", 1899 | "reference": "b78388f096f669f9a9f15dabe5fa73c4d9fd9a09" 1900 | }, 1901 | "dist": { 1902 | "type": "zip", 1903 | "url": "https://api.github.com/repos/zendframework/zend-stratigility/zipball/b78388f096f669f9a9f15dabe5fa73c4d9fd9a09", 1904 | "reference": "b78388f096f669f9a9f15dabe5fa73c4d9fd9a09", 1905 | "shasum": "" 1906 | }, 1907 | "require": { 1908 | "php": "^5.4.8 || ^7.0", 1909 | "psr/http-message": "~1.0.0", 1910 | "zendframework/zend-escaper": "~2.3" 1911 | }, 1912 | "require-dev": { 1913 | "phpunit/phpunit": "~4.7", 1914 | "squizlabs/php_codesniffer": "^2.3.1", 1915 | "zendframework/zend-diactoros": "~1.0" 1916 | }, 1917 | "suggest": { 1918 | "psr/http-message-implementation": "Please install a psr/http-message-implementation to consume Stratigility; e.g., zendframework/zend-diactoros" 1919 | }, 1920 | "type": "library", 1921 | "extra": { 1922 | "branch-alias": { 1923 | "dev-master": "1.2-dev", 1924 | "dev-develop": "1.3-dev" 1925 | } 1926 | }, 1927 | "autoload": { 1928 | "psr-4": { 1929 | "Zend\\Stratigility\\": "src/" 1930 | } 1931 | }, 1932 | "notification-url": "https://packagist.org/downloads/", 1933 | "license": [ 1934 | "BSD-3-Clause" 1935 | ], 1936 | "description": "Middleware for PHP", 1937 | "homepage": "https://github.com/zendframework/zend-stratigility", 1938 | "keywords": [ 1939 | "http", 1940 | "middleware", 1941 | "psr-7" 1942 | ], 1943 | "time": "2016-03-24 22:10:30" 1944 | } 1945 | ], 1946 | "packages-dev": [], 1947 | "aliases": [], 1948 | "minimum-stability": "stable", 1949 | "stability-flags": { 1950 | "bernard/bernard": 20 1951 | }, 1952 | "prefer-stable": false, 1953 | "prefer-lowest": false, 1954 | "platform": { 1955 | "php": "^7.0", 1956 | "ext-pdo": "*", 1957 | "ext-pdo_sqlite": "*" 1958 | }, 1959 | "platform-dev": [] 1960 | } 1961 | -------------------------------------------------------------------------------- /container.php: -------------------------------------------------------------------------------- 1 | [ 50 | Connection::class => function () { 51 | $connection = DriverManager::getConnection([ 52 | 'driverClass' => Driver::class, 53 | 'path' => __DIR__ . '/data/db.sqlite3', 54 | ]); 55 | 56 | try { 57 | $schema = $connection->getSchemaManager()->createSchema(); 58 | 59 | EventStoreSchema::createSingleStream($schema, 'event_stream', true); 60 | 61 | foreach ($schema->toSql($connection->getDatabasePlatform()) as $sql) { 62 | $connection->exec($sql); 63 | } 64 | } catch (SchemaException $ignored) { 65 | } 66 | 67 | return $connection; 68 | }, 69 | 70 | EventStore::class => function (ContainerInterface $container) { 71 | $eventBus = new EventBus(); 72 | $eventStore = new EventStore( 73 | new DoctrineEventStoreAdapter( 74 | $container->get(Connection::class), 75 | new FQCNMessageFactory(), 76 | new NoOpMessageConverter(), 77 | new JsonPayloadSerializer() 78 | ), 79 | new ProophActionEventEmitter() 80 | ); 81 | 82 | $eventBus->utilize(new class ($container, $container) implements ActionEventListenerAggregate 83 | { 84 | /** 85 | * @var ContainerInterface 86 | */ 87 | private $eventHandlers; 88 | 89 | /** 90 | * @var ContainerInterface 91 | */ 92 | private $projectors; 93 | 94 | public function __construct( 95 | ContainerInterface $eventHandlers, 96 | ContainerInterface $projectors 97 | ) { 98 | $this->eventHandlers = $eventHandlers; 99 | $this->projectors = $projectors; 100 | } 101 | 102 | public function attach(ActionEventEmitter $dispatcher) 103 | { 104 | $dispatcher->attachListener(MessageBus::EVENT_ROUTE, [$this, 'onRoute']); 105 | } 106 | 107 | public function detach(ActionEventEmitter $dispatcher) 108 | { 109 | throw new \BadMethodCallException('Not implemented'); 110 | } 111 | 112 | public function onRoute(ActionEvent $actionEvent) 113 | { 114 | $messageName = (string) $actionEvent->getParam(MessageBus::EVENT_PARAM_MESSAGE_NAME); 115 | 116 | $handlers = []; 117 | 118 | $listeners = $messageName . '-listeners'; 119 | $projectors = $messageName . '-projectors'; 120 | 121 | if ($this->projectors->has($projectors)) { 122 | $handlers = array_merge($handlers, $this->eventHandlers->get($projectors)); 123 | } 124 | 125 | if ($this->eventHandlers->has($listeners)) { 126 | $handlers = array_merge($handlers, $this->eventHandlers->get($listeners)); 127 | } 128 | 129 | if ($handlers) { 130 | $actionEvent->setParam(EventBus::EVENT_PARAM_EVENT_LISTENERS, $handlers); 131 | } 132 | } 133 | }); 134 | 135 | (new EventPublisher($eventBus))->setUp($eventStore); 136 | 137 | return $eventStore; 138 | }, 139 | 140 | CommandBus::class => function (ContainerInterface $container) : CommandBus { 141 | $commandBus = new CommandBus(); 142 | 143 | $commandBus->utilize(new ServiceLocatorPlugin($container)); 144 | $commandBus->utilize(new class implements ActionEventListenerAggregate { 145 | public function attach(ActionEventEmitter $dispatcher) 146 | { 147 | $dispatcher->attachListener(MessageBus::EVENT_ROUTE, [$this, 'onRoute']); 148 | } 149 | 150 | public function detach(ActionEventEmitter $dispatcher) 151 | { 152 | throw new \BadMethodCallException('Not implemented'); 153 | } 154 | 155 | public function onRoute(ActionEvent $actionEvent) 156 | { 157 | $actionEvent->setParam( 158 | MessageBus::EVENT_PARAM_MESSAGE_HANDLER, 159 | (string) $actionEvent->getParam(MessageBus::EVENT_PARAM_MESSAGE_NAME) 160 | ); 161 | } 162 | }); 163 | 164 | $transactionManager = new TransactionManager(); 165 | $transactionManager->setUp($container->get(EventStore::class)); 166 | 167 | $commandBus->utilize($transactionManager); 168 | 169 | return $commandBus; 170 | }, 171 | 172 | // ignore this - this is async stuff 173 | // we'll get to it later 174 | 175 | QueueFactory::class => function () : QueueFactory { 176 | return new PersistentFactory( 177 | new FlatFileDriver(__DIR__ . '/data/bernard'), 178 | new BernardSerializer(new FQCNMessageFactory(), new NoOpMessageConverter()) 179 | ); 180 | }, 181 | 182 | Queue::class => function (ContainerInterface $container) : Queue { 183 | return $container->get(QueueFactory::class)->create('commands'); 184 | }, 185 | 186 | MessageProducer::class => function (ContainerInterface $container) : MessageProducer { 187 | return new BernardMessageProducer( 188 | new Producer($container->get(QueueFactory::class),new EventDispatcher()), 189 | 'commands' 190 | ); 191 | }, 192 | 193 | // Command -> CommandHandlerFactory 194 | // this is where most of the work will be done (by you!) 195 | Command\RegisterNewBuilding::class => function (ContainerInterface $container) : callable { 196 | $buildings = $container->get(BuildingRepositoryInterface::class); 197 | 198 | return function (Command\RegisterNewBuilding $command) use ($buildings) { 199 | $buildings->add(Building::new($command->name())); 200 | }; 201 | }, 202 | BuildingRepositoryInterface::class => function (ContainerInterface $container) : BuildingRepositoryInterface { 203 | return new BuildingRepository( 204 | new AggregateRepository( 205 | $container->get(EventStore::class), 206 | AggregateType::fromAggregateRootClass(Building::class), 207 | new AggregateTranslator() 208 | ) 209 | ); 210 | }, 211 | ], 212 | ]); -------------------------------------------------------------------------------- /data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | ./tests/BuildingTest 17 | 18 | 19 | 20 | 21 | ./src 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /public/.gitignore: -------------------------------------------------------------------------------- 1 | *.json -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | writeToOutput(false); 33 | $whoops->allowQuit(false); 34 | $whoops->pushHandler($whoopsHandler); 35 | 36 | $app = new Application(new FastRouteRouter(), $sm, new WhoopsErrorHandler($whoops, $whoopsHandler)); 37 | 38 | $app->pipeRoutingMiddleware(); 39 | 40 | $app->get('/', function (Request $request, Response $response) : Response { 41 | ob_start(); 42 | require __DIR__ . '/../template/index.php'; 43 | $content = ob_get_clean(); 44 | 45 | $response->getBody()->write($content); 46 | 47 | return $response; 48 | }); 49 | 50 | $app->post('/register-new-building', function (Request $request, Response $response) use ($sm) : Response { 51 | $commandBus = $sm->get(CommandBus::class); 52 | $commandBus->dispatch(Command\RegisterNewBuilding::fromName($request->getParsedBody()['name'])); 53 | 54 | return $response->withAddedHeader('Location', '/'); 55 | }); 56 | 57 | $app->get('/building/{buildingId}', function (Request $request, Response $response) : Response { 58 | $buildingId = Uuid::fromString($request->getAttribute('buildingId')); 59 | 60 | ob_start(); 61 | require __DIR__ . '/../template/building.php'; 62 | $content = ob_get_clean(); 63 | 64 | $response->getBody()->write($content); 65 | 66 | return $response; 67 | }); 68 | 69 | $app->post('/checkin/{buildingId}', function (Request $request, Response $response) use ($sm) : Response { 70 | 71 | }); 72 | 73 | $app->post('/checkout/{buildingId}', function (Request $request, Response $response) use ($sm) : Response { 74 | 75 | }); 76 | 77 | $app->pipeDispatchMiddleware(); 78 | 79 | $whoops->register(); 80 | $app->run(); 81 | }); -------------------------------------------------------------------------------- /src/Domain/Aggregate/Building.php: -------------------------------------------------------------------------------- 1 | recordThat(NewBuildingWasRegistered::occur( 28 | (string) Uuid::uuid4(), 29 | [ 30 | 'name' => $name 31 | ] 32 | )); 33 | 34 | return $self; 35 | } 36 | 37 | public function checkInUser(string $username) 38 | { 39 | // @TODO to be implemented 40 | } 41 | 42 | public function checkOutUser(string $username) 43 | { 44 | // @TODO to be implemented 45 | } 46 | 47 | public function whenNewBuildingWasRegistered(NewBuildingWasRegistered $event) 48 | { 49 | $this->uuid = $event->uuid(); 50 | $this->name = $event->name(); 51 | } 52 | 53 | /** 54 | * {@inheritDoc} 55 | */ 56 | protected function aggregateId() : string 57 | { 58 | return (string) $this->uuid; 59 | } 60 | 61 | /** 62 | * {@inheritDoc} 63 | */ 64 | public function id() : string 65 | { 66 | return $this->aggregateId(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Domain/Command/RegisterNewBuilding.php: -------------------------------------------------------------------------------- 1 | init(); 19 | 20 | $this->name = $name; 21 | } 22 | 23 | public static function fromName(string $name) : self 24 | { 25 | return new self($name); 26 | } 27 | 28 | public function name() : string 29 | { 30 | return $this->name; 31 | } 32 | 33 | /** 34 | * {@inheritDoc} 35 | */ 36 | public function payload() : array 37 | { 38 | return [ 39 | 'name' => $this->name, 40 | ]; 41 | } 42 | 43 | /** 44 | * {@inheritDoc} 45 | */ 46 | protected function setPayload(array $payload) 47 | { 48 | $this->name = $payload['name']; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Domain/DomainEvent/NewBuildingWasRegistered.php: -------------------------------------------------------------------------------- 1 | payload['name']; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Domain/Repository/BuildingRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | aggregateRepository = $aggregateRepository; 22 | } 23 | 24 | public function add(Building $building) 25 | { 26 | $this->aggregateRepository->addAggregateRoot($building); 27 | } 28 | 29 | public function get(Uuid $id) : Building 30 | { 31 | return $this->aggregateRepository->getAggregateRoot($id->toString()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /template/building.php: -------------------------------------------------------------------------------- 1 | 2 |

Welcome to CQRS+ES building

3 | 4 |

Check In:

5 |
6 | 7 | 8 | 9 |
10 | 11 |

Check Out:

12 |
13 | 14 | 15 | 16 |
17 | -------------------------------------------------------------------------------- /template/index.php: -------------------------------------------------------------------------------- 1 | 2 |

Register Building

3 | 4 |
5 | 6 | 7 | 8 |
9 | -------------------------------------------------------------------------------- /worker/worker.php: -------------------------------------------------------------------------------- 1 | get(CommandBus::class), new EventBus()), new EventDispatcher())) 25 | ->consume($sm->get(Queue::class)); 26 | }); 27 | --------------------------------------------------------------------------------