├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── assignments ├── 01.md ├── 02.md ├── 03.md ├── 04.md ├── 05.md ├── 06.md ├── 07.md ├── 08.md └── 09.md ├── bin ├── composer.sh ├── run_tests.sh └── sandbox.sh ├── composer.json ├── composer.lock ├── docker-compose.yml ├── docker └── devtools │ └── Dockerfile ├── phpunit.xml.dist ├── sandbox.php ├── src └── MeetupOrganizing │ ├── Domain │ └── Model │ │ ├── MeetupGroup │ │ ├── MeetupGroup.php │ │ ├── MeetupGroupId.php │ │ └── MeetupGroupRepository.php │ │ └── User │ │ ├── User.php │ │ ├── UserId.php │ │ └── UserRepository.php │ └── Infrastructure │ └── Persistence │ ├── InMemoryMeetupGroupRepository.php │ └── InMemoryUserRepository.php └── test ├── Test └── Unit │ └── MeetupOrganizing │ ├── Domain │ └── Model │ │ ├── MeetupGroupTest.php │ │ └── UserTest.php │ └── Infrastructure │ └── Persistence │ ├── InMemoryMeetupGroupRepositoryTest.php │ └── InMemoryUserRepositoryTest.php └── bootstrap.php /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | 8 | [*.{php,json,yaml}] 9 | indent_style = space 10 | indent_size = 4 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Ibuildings, 2017 Matthias Noback 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 furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | 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. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Code and assignments for the "Tactical DDD" workshop module 2 | 3 | ## Requirements 4 | 5 | - [Docker Engine](https://docs.docker.com/engine/installation/) 6 | - [Docker Compose](https://docs.docker.com/compose/install/) 7 | 8 | ## Getting started 9 | 10 | - Clone this repository and `cd` into it. 11 | - Run `docker-compose pull`. 12 | - Run `bin/composer.sh install --prefer-dist` to install the project's dependencies. 13 | - [Follow the instructions](https://github.com/matthiasnoback/php-workshop-tools/blob/master/README.md) for setting environment variables and configuring PhpStorm for debugging. 14 | 15 | ## Running development tools 16 | 17 | - Run `bin/composer.sh` to use Composer (e.g. `bin/composer.sh require symfony/var-dumper`). 18 | - Run `bin/run_tests.sh` to run the tests. 19 | - Run `bin/sandbox.sh` to run the `sandbox.php` script. 20 | -------------------------------------------------------------------------------- /assignments/01.md: -------------------------------------------------------------------------------- 1 | # Design the Meetup aggregate 2 | 3 | ## Briefing by the domain expert 4 | 5 | A meetup is a get-together organized by a particular meetup group. When a meetup organiser wants to schedule a meetup, it needs to provide at least a working title (e.g. the name of the talk or workshop that is planned) and the meetup itself should be scheduled for a particular date and time (even though it might be rescheduled later). This way, people can at least save the preliminary date. 6 | 7 | When the meetup has been scheduled, users can respond to the RSVP with a "yes" or a "no". The organiser of the meetup always RSVPs with a "yes". 8 | 9 | ## Consequences 10 | 11 | - We have to implement a `Meetup` class. 12 | - We have to implement an `Rsvp` class. 13 | 14 | ## Hints 15 | 16 | - Prefer value objects over (child) entities. 17 | - A meetup should be linked to the person who scheduled it as well as the meetup group it belongs to. `User` and `MeetupGroup` entity classes have already been defined for this purpose. 18 | - No need to create a repository yet. 19 | - Use value objects for identities. 20 | - Use `Uuid::uuid4()` to generate unique identities. 21 | - Consider the need for an identity class. 22 | - Write tests or if you're not familiar with that, manually test your stuff in a simple `sandbox.php` (this code isn't going to end up in production ;)). 23 | -------------------------------------------------------------------------------- /assignments/02.md: -------------------------------------------------------------------------------- 1 | # Redesigning the Meetup aggregate 2 | 3 | ## Briefing by the domain expert 4 | 5 | After an RSVP has been posted, a user should be able to change their answer (from "yes" to "no" and vice versa). 6 | 7 | ## Consequences 8 | 9 | - We have to implement the `Rsvp` class as an entity. 10 | 11 | ## Hints 12 | 13 | - It won't be a child entity, but an aggregate on its own. 14 | -------------------------------------------------------------------------------- /assignments/03.md: -------------------------------------------------------------------------------- 1 | # Implement automatic Rsvp "yes" for the organizer 2 | 3 | Since we now create separate `Meetup` and `Rsvp` aggregates, the `Meetup` aggregate can't "rsvp yes" for the organizer immediately, that is, within one transaction. It should happen in another transaction. So this business rule be enforced in an eventually consistent way. 4 | 5 | ## Consequences 6 | 7 | - Scheduling a meetup should trigger the recording of a domain event. You can "record" it in an internal array of event objects. 8 | - In the sandbox you should be able to take out the events from the `Meetup` aggregate by calling some method on it. 9 | - A subscriber for this particular event is going to create the `Rsvp` aggregate for the organizer. 10 | 11 | ## Hints 12 | 13 | - In the sandbox an instantiated event dispatcher is already available. You can register event subscribers to it by providing the full class name as the name of the event. 14 | - No need to implement full event-sourcing (yet). 15 | -------------------------------------------------------------------------------- /assignments/04.md: -------------------------------------------------------------------------------- 1 | # Notify group members about a scheduled meetup 2 | 3 | ## Briefing by the domain expert 4 | 5 | Whenever a meetup has been scheduled we need to notify every group member of it. At least we'll send them an email, but once we have our mobile app ready, we should also send a push notification to the member's phone. 6 | 7 | ## Consequences 8 | 9 | - Scheduling a meetup should trigger the recording of a domain event. 10 | - A subscriber for this particular event is going to collect the email addresses of users who are in fact a member of the meetup group this meetup was scheduled for. 11 | -------------------------------------------------------------------------------- /assignments/05.md: -------------------------------------------------------------------------------- 1 | # Create properly bounded contexts 2 | 3 | We currently work in one context: the `MeetupOrganizing` context. We can see some concepts becoming stretched, like `User`. When organizing a meetup, we're talking not about "users" but about "organizers". The same for `Rsvp`: someone who says "yes, I'll attend", is called an "attendee", not a "user". 4 | 5 | A "user" is only relevant in the context of "meetup membership". 6 | 7 | ## Consequences 8 | 9 | - User-related classes should be moved to their own root namespace, `MeetupMembership`, which manages accounts and paid memberships (which are required for being an organizer). 10 | 11 | ## Questions 12 | 13 | - How would you be able to use the actual identifiers from the `MeetupMembership` context inside the `MeetupOrganizing` context? After all, it should be possible to match these, to find out which users are actually organizers, or if an organizer is an existing user who paid their bills, etc. 14 | 15 | The instructor will show you the full implementation for integrating the new (bounded) contexts. 16 | -------------------------------------------------------------------------------- /assignments/06.md: -------------------------------------------------------------------------------- 1 | # Design application services to interact with domain objects 2 | 3 | - Define the following command classes: 4 | - `ScheduleMeetup` 5 | - `RsvpYes` 6 | - Rewrite the sandbox script to make use of command objects and command handlers instead of making directly modifying domain objects. 7 | - Optionally write Behat scenarios for the use cases of this application. 8 | -------------------------------------------------------------------------------- /assignments/07.md: -------------------------------------------------------------------------------- 1 | # Implement a persistence-based repository using an event store 2 | 3 | ## Storing events 4 | 5 | - Events should be serializable to a string. 6 | - Events should carry the ID of the aggregate they belong to. 7 | - When the repository saves an aggregate, it retrieves new events from the aggregate and stores them instead. 8 | 9 | ## Reconstituting the aggregate 10 | 11 | - An aggregate can be retrieved from the repository by its ID. 12 | - The repository retrieves all the aggregate's events from the even store. 13 | - A static `reconstitute()` method on the aggregate receives the deserialized domain events for the aggregate. It uses the events to restore its last known state. 14 | 15 | ## Hints: 16 | 17 | - As a quick solution you could use PHP's native `serialize()` and `unserialize()` functions to convert events to strings and back again. 18 | - You can assume that the events need no sorting. 19 | - You don't have to think about concurrent updates for now. 20 | -------------------------------------------------------------------------------- /assignments/08.md: -------------------------------------------------------------------------------- 1 | # Add a location attribute to a meetup 2 | 3 | The location of a meetup consists of an address (a single string, which doesn't have to be validated) and an exact location, in terms of a latitude and longitude (both will be floats). 4 | 5 | Consider which values should be a consistent whole and will always change together. Define some constraints, like: 6 | 7 | - The address shouldn't be empty. 8 | - The latitude should be at least ... and at most ... 9 | - The longitude should be at least ... and at most ... 10 | - ... 11 | 12 | Now design value objects to encapsulate the data as well as these rules. Make sure you write unit tests, proving that the objects can only be constructed in valid ways. 13 | 14 | Finally, add the location as an attribute to the `Meetup` entity. Consider the following scenario: we can schedule a meetup without knowing the location yet. So we need two ways of assigning a location: when we schedule it, or afterwards, when we found a location for it (and maybe even a third way: what if we want to relocate it?). 15 | -------------------------------------------------------------------------------- /assignments/09.md: -------------------------------------------------------------------------------- 1 | # Build up a read model 2 | 3 | So far, our aggregates are perfect *write models*: they don't have any query methods. 4 | 5 | We would like to know something about our domain objects though. For example, we want to be able to answer the following question: 6 | 7 | > How many times has replied "yes" to a meetup? 8 | 9 | We don't need to do any complicated queries to answer this question, as long as we continuously keep track of every time a user submits "RSVP yes". In that case we could simply increment a counter for that particular user. Also, whenever this user changes their RSVP to "no" again (only if they *change* it, not if it's their first answer), we should decrement the counter to reflect the latest changes to the *write model*. 10 | 11 | Now, create event subscribers which listen to the relevant events and update a simple read model (maybe just an array of which the keys are user IDs and the values are the counter for the number of RSVP "yes"s). 12 | -------------------------------------------------------------------------------- /bin/composer.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker-compose run --rm devtools composer $@ 4 | -------------------------------------------------------------------------------- /bin/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker-compose run --rm devtools /bin/bash -c "vendor/bin/phpunit" 4 | -------------------------------------------------------------------------------- /bin/sandbox.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker-compose run --rm devtools /bin/bash -c "php sandbox.php" 4 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "ramsey/uuid": "^3.4", 4 | "beberlei/assert": "^2.5", 5 | "matthiasnoback/php-workshop-tools": "^0.9" 6 | }, 7 | "require-dev": { 8 | "php": "^7.0", 9 | "phpunit/phpunit": "^5.4", 10 | "behat/behat": "^3.3" 11 | }, 12 | "license": "MIT", 13 | "authors": [ 14 | { 15 | "name": "Matthias Noback", 16 | "email": "matthiasnoback@gmail.com" 17 | } 18 | ], 19 | "autoload": { 20 | "psr-4": { 21 | "": "src/" 22 | } 23 | }, 24 | "autoload-dev": { 25 | "psr-4": { 26 | "Test\\": "test/" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /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": "2d67c965cb24fac7584a118652594717", 8 | "packages": [ 9 | { 10 | "name": "beberlei/assert", 11 | "version": "v2.7.4", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/beberlei/assert.git", 15 | "reference": "3ee3bc468a3ce4bbfc3d74f53c6cdb5242d39d1a" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/beberlei/assert/zipball/3ee3bc468a3ce4bbfc3d74f53c6cdb5242d39d1a", 20 | "reference": "3ee3bc468a3ce4bbfc3d74f53c6cdb5242d39d1a", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "ext-mbstring": "*", 25 | "php": ">=5.3" 26 | }, 27 | "require-dev": { 28 | "friendsofphp/php-cs-fixer": "^2.1.1", 29 | "phpunit/phpunit": "^4|^5" 30 | }, 31 | "type": "library", 32 | "autoload": { 33 | "psr-4": { 34 | "Assert\\": "lib/Assert" 35 | }, 36 | "files": [ 37 | "lib/Assert/functions.php" 38 | ] 39 | }, 40 | "notification-url": "https://packagist.org/downloads/", 41 | "license": [ 42 | "BSD-2-Clause" 43 | ], 44 | "authors": [ 45 | { 46 | "name": "Benjamin Eberlei", 47 | "email": "kontakt@beberlei.de", 48 | "role": "Lead Developer" 49 | }, 50 | { 51 | "name": "Richard Quadling", 52 | "email": "rquadling@gmail.com", 53 | "role": "Collaborator" 54 | } 55 | ], 56 | "description": "Thin assertion library for input validation in business models.", 57 | "keywords": [ 58 | "assert", 59 | "assertion", 60 | "validation" 61 | ], 62 | "time": "2017-03-14T18:06:52+00:00" 63 | }, 64 | { 65 | "name": "matthiasnoback/naive-serializer", 66 | "version": "v0.4.0", 67 | "source": { 68 | "type": "git", 69 | "url": "https://github.com/matthiasnoback/naive-serializer.git", 70 | "reference": "005edb28adae5ffe3e50352a611ad0008863d4dc" 71 | }, 72 | "dist": { 73 | "type": "zip", 74 | "url": "https://api.github.com/repos/matthiasnoback/naive-serializer/zipball/005edb28adae5ffe3e50352a611ad0008863d4dc", 75 | "reference": "005edb28adae5ffe3e50352a611ad0008863d4dc", 76 | "shasum": "" 77 | }, 78 | "require": { 79 | "beberlei/assert": "^2.7", 80 | "php": "^7.0", 81 | "phpdocumentor/reflection-docblock": "^3.1" 82 | }, 83 | "require-dev": { 84 | "phpunit/phpunit": "^5.5" 85 | }, 86 | "type": "library", 87 | "autoload": { 88 | "psr-4": { 89 | "NaiveSerializer\\": "src/" 90 | } 91 | }, 92 | "notification-url": "https://packagist.org/downloads/", 93 | "license": [ 94 | "MIT" 95 | ], 96 | "authors": [ 97 | { 98 | "name": "Matthias Noback", 99 | "email": "matthiasnoback@gmail.com" 100 | } 101 | ], 102 | "time": "2017-02-13T19:13:11+00:00" 103 | }, 104 | { 105 | "name": "matthiasnoback/php-workshop-tools", 106 | "version": "v0.9.1", 107 | "source": { 108 | "type": "git", 109 | "url": "https://github.com/matthiasnoback/php-workshop-tools.git", 110 | "reference": "dda08dfd776c34234e2b7a325daa5349f8022d58" 111 | }, 112 | "dist": { 113 | "type": "zip", 114 | "url": "https://api.github.com/repos/matthiasnoback/php-workshop-tools/zipball/dda08dfd776c34234e2b7a325daa5349f8022d58", 115 | "reference": "dda08dfd776c34234e2b7a325daa5349f8022d58", 116 | "shasum": "" 117 | }, 118 | "require": { 119 | "beberlei/assert": "^2.7", 120 | "matthiasnoback/naive-serializer": "^0.4", 121 | "php": "^7.1", 122 | "ramsey/uuid": "^3.4", 123 | "symfony/var-dumper": "^3.2" 124 | }, 125 | "require-dev": { 126 | "phpunit/phpunit": "^5.5" 127 | }, 128 | "type": "library", 129 | "autoload": { 130 | "psr-4": { 131 | "": "src/" 132 | }, 133 | "files": [ 134 | "src/Common/CommandLine/functions.php", 135 | "src/Common/Resilience/functions.php" 136 | ] 137 | }, 138 | "notification-url": "https://packagist.org/downloads/", 139 | "license": [ 140 | "MIT" 141 | ], 142 | "authors": [ 143 | { 144 | "name": "Matthias Noback", 145 | "email": "matthiasnoback@gmail.com" 146 | } 147 | ], 148 | "time": "2017-05-06T07:30:46+00:00" 149 | }, 150 | { 151 | "name": "paragonie/random_compat", 152 | "version": "v2.0.10", 153 | "source": { 154 | "type": "git", 155 | "url": "https://github.com/paragonie/random_compat.git", 156 | "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d" 157 | }, 158 | "dist": { 159 | "type": "zip", 160 | "url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d", 161 | "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d", 162 | "shasum": "" 163 | }, 164 | "require": { 165 | "php": ">=5.2.0" 166 | }, 167 | "require-dev": { 168 | "phpunit/phpunit": "4.*|5.*" 169 | }, 170 | "suggest": { 171 | "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." 172 | }, 173 | "type": "library", 174 | "autoload": { 175 | "files": [ 176 | "lib/random.php" 177 | ] 178 | }, 179 | "notification-url": "https://packagist.org/downloads/", 180 | "license": [ 181 | "MIT" 182 | ], 183 | "authors": [ 184 | { 185 | "name": "Paragon Initiative Enterprises", 186 | "email": "security@paragonie.com", 187 | "homepage": "https://paragonie.com" 188 | } 189 | ], 190 | "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", 191 | "keywords": [ 192 | "csprng", 193 | "pseudorandom", 194 | "random" 195 | ], 196 | "time": "2017-03-13T16:27:32+00:00" 197 | }, 198 | { 199 | "name": "phpdocumentor/reflection-common", 200 | "version": "1.0", 201 | "source": { 202 | "type": "git", 203 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 204 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" 205 | }, 206 | "dist": { 207 | "type": "zip", 208 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", 209 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", 210 | "shasum": "" 211 | }, 212 | "require": { 213 | "php": ">=5.5" 214 | }, 215 | "require-dev": { 216 | "phpunit/phpunit": "^4.6" 217 | }, 218 | "type": "library", 219 | "extra": { 220 | "branch-alias": { 221 | "dev-master": "1.0.x-dev" 222 | } 223 | }, 224 | "autoload": { 225 | "psr-4": { 226 | "phpDocumentor\\Reflection\\": [ 227 | "src" 228 | ] 229 | } 230 | }, 231 | "notification-url": "https://packagist.org/downloads/", 232 | "license": [ 233 | "MIT" 234 | ], 235 | "authors": [ 236 | { 237 | "name": "Jaap van Otterdijk", 238 | "email": "opensource@ijaap.nl" 239 | } 240 | ], 241 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 242 | "homepage": "http://www.phpdoc.org", 243 | "keywords": [ 244 | "FQSEN", 245 | "phpDocumentor", 246 | "phpdoc", 247 | "reflection", 248 | "static analysis" 249 | ], 250 | "time": "2015-12-27T11:43:31+00:00" 251 | }, 252 | { 253 | "name": "phpdocumentor/reflection-docblock", 254 | "version": "3.1.1", 255 | "source": { 256 | "type": "git", 257 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 258 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" 259 | }, 260 | "dist": { 261 | "type": "zip", 262 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", 263 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", 264 | "shasum": "" 265 | }, 266 | "require": { 267 | "php": ">=5.5", 268 | "phpdocumentor/reflection-common": "^1.0@dev", 269 | "phpdocumentor/type-resolver": "^0.2.0", 270 | "webmozart/assert": "^1.0" 271 | }, 272 | "require-dev": { 273 | "mockery/mockery": "^0.9.4", 274 | "phpunit/phpunit": "^4.4" 275 | }, 276 | "type": "library", 277 | "autoload": { 278 | "psr-4": { 279 | "phpDocumentor\\Reflection\\": [ 280 | "src/" 281 | ] 282 | } 283 | }, 284 | "notification-url": "https://packagist.org/downloads/", 285 | "license": [ 286 | "MIT" 287 | ], 288 | "authors": [ 289 | { 290 | "name": "Mike van Riel", 291 | "email": "me@mikevanriel.com" 292 | } 293 | ], 294 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 295 | "time": "2016-09-30T07:12:33+00:00" 296 | }, 297 | { 298 | "name": "phpdocumentor/type-resolver", 299 | "version": "0.2.1", 300 | "source": { 301 | "type": "git", 302 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 303 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" 304 | }, 305 | "dist": { 306 | "type": "zip", 307 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", 308 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", 309 | "shasum": "" 310 | }, 311 | "require": { 312 | "php": ">=5.5", 313 | "phpdocumentor/reflection-common": "^1.0" 314 | }, 315 | "require-dev": { 316 | "mockery/mockery": "^0.9.4", 317 | "phpunit/phpunit": "^5.2||^4.8.24" 318 | }, 319 | "type": "library", 320 | "extra": { 321 | "branch-alias": { 322 | "dev-master": "1.0.x-dev" 323 | } 324 | }, 325 | "autoload": { 326 | "psr-4": { 327 | "phpDocumentor\\Reflection\\": [ 328 | "src/" 329 | ] 330 | } 331 | }, 332 | "notification-url": "https://packagist.org/downloads/", 333 | "license": [ 334 | "MIT" 335 | ], 336 | "authors": [ 337 | { 338 | "name": "Mike van Riel", 339 | "email": "me@mikevanriel.com" 340 | } 341 | ], 342 | "time": "2016-11-25T06:54:22+00:00" 343 | }, 344 | { 345 | "name": "ramsey/uuid", 346 | "version": "3.5.2", 347 | "source": { 348 | "type": "git", 349 | "url": "https://github.com/ramsey/uuid.git", 350 | "reference": "5677cfe02397dd6b58c861870dfaa5d9007d3954" 351 | }, 352 | "dist": { 353 | "type": "zip", 354 | "url": "https://api.github.com/repos/ramsey/uuid/zipball/5677cfe02397dd6b58c861870dfaa5d9007d3954", 355 | "reference": "5677cfe02397dd6b58c861870dfaa5d9007d3954", 356 | "shasum": "" 357 | }, 358 | "require": { 359 | "paragonie/random_compat": "^1.0|^2.0", 360 | "php": ">=5.4" 361 | }, 362 | "replace": { 363 | "rhumsaa/uuid": "self.version" 364 | }, 365 | "require-dev": { 366 | "apigen/apigen": "^4.1", 367 | "codeception/aspect-mock": "1.0.0", 368 | "doctrine/annotations": "~1.2.0", 369 | "goaop/framework": "1.0.0-alpha.2", 370 | "ircmaxell/random-lib": "^1.1", 371 | "jakub-onderka/php-parallel-lint": "^0.9.0", 372 | "mockery/mockery": "^0.9.4", 373 | "moontoast/math": "^1.1", 374 | "php-mock/php-mock-phpunit": "^0.3|^1.1", 375 | "phpunit/phpunit": "^4.7|>=5.0 <5.4", 376 | "satooshi/php-coveralls": "^0.6.1", 377 | "squizlabs/php_codesniffer": "^2.3" 378 | }, 379 | "suggest": { 380 | "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", 381 | "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", 382 | "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", 383 | "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", 384 | "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", 385 | "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." 386 | }, 387 | "type": "library", 388 | "extra": { 389 | "branch-alias": { 390 | "dev-master": "3.x-dev" 391 | } 392 | }, 393 | "autoload": { 394 | "psr-4": { 395 | "Ramsey\\Uuid\\": "src/" 396 | } 397 | }, 398 | "notification-url": "https://packagist.org/downloads/", 399 | "license": [ 400 | "MIT" 401 | ], 402 | "authors": [ 403 | { 404 | "name": "Marijn Huizendveld", 405 | "email": "marijn.huizendveld@gmail.com" 406 | }, 407 | { 408 | "name": "Thibaud Fabre", 409 | "email": "thibaud@aztech.io" 410 | }, 411 | { 412 | "name": "Ben Ramsey", 413 | "email": "ben@benramsey.com", 414 | "homepage": "https://benramsey.com" 415 | } 416 | ], 417 | "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", 418 | "homepage": "https://github.com/ramsey/uuid", 419 | "keywords": [ 420 | "guid", 421 | "identifier", 422 | "uuid" 423 | ], 424 | "time": "2016-11-22T19:21:44+00:00" 425 | }, 426 | { 427 | "name": "symfony/polyfill-mbstring", 428 | "version": "v1.3.0", 429 | "source": { 430 | "type": "git", 431 | "url": "https://github.com/symfony/polyfill-mbstring.git", 432 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" 433 | }, 434 | "dist": { 435 | "type": "zip", 436 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", 437 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", 438 | "shasum": "" 439 | }, 440 | "require": { 441 | "php": ">=5.3.3" 442 | }, 443 | "suggest": { 444 | "ext-mbstring": "For best performance" 445 | }, 446 | "type": "library", 447 | "extra": { 448 | "branch-alias": { 449 | "dev-master": "1.3-dev" 450 | } 451 | }, 452 | "autoload": { 453 | "psr-4": { 454 | "Symfony\\Polyfill\\Mbstring\\": "" 455 | }, 456 | "files": [ 457 | "bootstrap.php" 458 | ] 459 | }, 460 | "notification-url": "https://packagist.org/downloads/", 461 | "license": [ 462 | "MIT" 463 | ], 464 | "authors": [ 465 | { 466 | "name": "Nicolas Grekas", 467 | "email": "p@tchwork.com" 468 | }, 469 | { 470 | "name": "Symfony Community", 471 | "homepage": "https://symfony.com/contributors" 472 | } 473 | ], 474 | "description": "Symfony polyfill for the Mbstring extension", 475 | "homepage": "https://symfony.com", 476 | "keywords": [ 477 | "compatibility", 478 | "mbstring", 479 | "polyfill", 480 | "portable", 481 | "shim" 482 | ], 483 | "time": "2016-11-14T01:06:16+00:00" 484 | }, 485 | { 486 | "name": "symfony/var-dumper", 487 | "version": "v3.2.6", 488 | "source": { 489 | "type": "git", 490 | "url": "https://github.com/symfony/var-dumper.git", 491 | "reference": "4100f347aff890bc16b0b4b42843b599db257b2d" 492 | }, 493 | "dist": { 494 | "type": "zip", 495 | "url": "https://api.github.com/repos/symfony/var-dumper/zipball/4100f347aff890bc16b0b4b42843b599db257b2d", 496 | "reference": "4100f347aff890bc16b0b4b42843b599db257b2d", 497 | "shasum": "" 498 | }, 499 | "require": { 500 | "php": ">=5.5.9", 501 | "symfony/polyfill-mbstring": "~1.0" 502 | }, 503 | "conflict": { 504 | "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" 505 | }, 506 | "require-dev": { 507 | "twig/twig": "~1.20|~2.0" 508 | }, 509 | "suggest": { 510 | "ext-symfony_debug": "" 511 | }, 512 | "type": "library", 513 | "extra": { 514 | "branch-alias": { 515 | "dev-master": "3.2-dev" 516 | } 517 | }, 518 | "autoload": { 519 | "files": [ 520 | "Resources/functions/dump.php" 521 | ], 522 | "psr-4": { 523 | "Symfony\\Component\\VarDumper\\": "" 524 | }, 525 | "exclude-from-classmap": [ 526 | "/Tests/" 527 | ] 528 | }, 529 | "notification-url": "https://packagist.org/downloads/", 530 | "license": [ 531 | "MIT" 532 | ], 533 | "authors": [ 534 | { 535 | "name": "Nicolas Grekas", 536 | "email": "p@tchwork.com" 537 | }, 538 | { 539 | "name": "Symfony Community", 540 | "homepage": "https://symfony.com/contributors" 541 | } 542 | ], 543 | "description": "Symfony mechanism for exploring and dumping PHP variables", 544 | "homepage": "https://symfony.com", 545 | "keywords": [ 546 | "debug", 547 | "dump" 548 | ], 549 | "time": "2017-02-20T13:45:48+00:00" 550 | }, 551 | { 552 | "name": "webmozart/assert", 553 | "version": "1.2.0", 554 | "source": { 555 | "type": "git", 556 | "url": "https://github.com/webmozart/assert.git", 557 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" 558 | }, 559 | "dist": { 560 | "type": "zip", 561 | "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", 562 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", 563 | "shasum": "" 564 | }, 565 | "require": { 566 | "php": "^5.3.3 || ^7.0" 567 | }, 568 | "require-dev": { 569 | "phpunit/phpunit": "^4.6", 570 | "sebastian/version": "^1.0.1" 571 | }, 572 | "type": "library", 573 | "extra": { 574 | "branch-alias": { 575 | "dev-master": "1.3-dev" 576 | } 577 | }, 578 | "autoload": { 579 | "psr-4": { 580 | "Webmozart\\Assert\\": "src/" 581 | } 582 | }, 583 | "notification-url": "https://packagist.org/downloads/", 584 | "license": [ 585 | "MIT" 586 | ], 587 | "authors": [ 588 | { 589 | "name": "Bernhard Schussek", 590 | "email": "bschussek@gmail.com" 591 | } 592 | ], 593 | "description": "Assertions to validate method input/output with nice error messages.", 594 | "keywords": [ 595 | "assert", 596 | "check", 597 | "validate" 598 | ], 599 | "time": "2016-11-23T20:04:58+00:00" 600 | } 601 | ], 602 | "packages-dev": [ 603 | { 604 | "name": "behat/behat", 605 | "version": "v3.3.0", 606 | "source": { 607 | "type": "git", 608 | "url": "https://github.com/Behat/Behat.git", 609 | "reference": "15a3a1857457eaa29cdf41564a5e421effb09526" 610 | }, 611 | "dist": { 612 | "type": "zip", 613 | "url": "https://api.github.com/repos/Behat/Behat/zipball/15a3a1857457eaa29cdf41564a5e421effb09526", 614 | "reference": "15a3a1857457eaa29cdf41564a5e421effb09526", 615 | "shasum": "" 616 | }, 617 | "require": { 618 | "behat/gherkin": "^4.4.4", 619 | "behat/transliterator": "~1.0", 620 | "container-interop/container-interop": "^1.1", 621 | "ext-mbstring": "*", 622 | "php": ">=5.3.3", 623 | "symfony/class-loader": "~2.1||~3.0", 624 | "symfony/config": "~2.3||~3.0", 625 | "symfony/console": "~2.5||~3.0", 626 | "symfony/dependency-injection": "~2.1||~3.0", 627 | "symfony/event-dispatcher": "~2.1||~3.0", 628 | "symfony/translation": "~2.3||~3.0", 629 | "symfony/yaml": "~2.1||~3.0" 630 | }, 631 | "require-dev": { 632 | "herrera-io/box": "~1.6.1", 633 | "phpunit/phpunit": "~4.5", 634 | "symfony/process": "~2.5|~3.0" 635 | }, 636 | "suggest": { 637 | "behat/mink-extension": "for integration with Mink testing framework", 638 | "behat/symfony2-extension": "for integration with Symfony2 web framework", 639 | "behat/yii-extension": "for integration with Yii web framework" 640 | }, 641 | "bin": [ 642 | "bin/behat" 643 | ], 644 | "type": "library", 645 | "extra": { 646 | "branch-alias": { 647 | "dev-master": "3.2.x-dev" 648 | } 649 | }, 650 | "autoload": { 651 | "psr-0": { 652 | "Behat\\Behat": "src/", 653 | "Behat\\Testwork": "src/" 654 | } 655 | }, 656 | "notification-url": "https://packagist.org/downloads/", 657 | "license": [ 658 | "MIT" 659 | ], 660 | "authors": [ 661 | { 662 | "name": "Konstantin Kudryashov", 663 | "email": "ever.zet@gmail.com", 664 | "homepage": "http://everzet.com" 665 | } 666 | ], 667 | "description": "Scenario-oriented BDD framework for PHP 5.3", 668 | "homepage": "http://behat.org/", 669 | "keywords": [ 670 | "Agile", 671 | "BDD", 672 | "ScenarioBDD", 673 | "Scrum", 674 | "StoryBDD", 675 | "User story", 676 | "business", 677 | "development", 678 | "documentation", 679 | "examples", 680 | "symfony", 681 | "testing" 682 | ], 683 | "time": "2016-12-25T13:43:52+00:00" 684 | }, 685 | { 686 | "name": "behat/gherkin", 687 | "version": "v4.4.5", 688 | "source": { 689 | "type": "git", 690 | "url": "https://github.com/Behat/Gherkin.git", 691 | "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74" 692 | }, 693 | "dist": { 694 | "type": "zip", 695 | "url": "https://api.github.com/repos/Behat/Gherkin/zipball/5c14cff4f955b17d20d088dec1bde61c0539ec74", 696 | "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74", 697 | "shasum": "" 698 | }, 699 | "require": { 700 | "php": ">=5.3.1" 701 | }, 702 | "require-dev": { 703 | "phpunit/phpunit": "~4.5|~5", 704 | "symfony/phpunit-bridge": "~2.7|~3", 705 | "symfony/yaml": "~2.3|~3" 706 | }, 707 | "suggest": { 708 | "symfony/yaml": "If you want to parse features, represented in YAML files" 709 | }, 710 | "type": "library", 711 | "extra": { 712 | "branch-alias": { 713 | "dev-master": "4.4-dev" 714 | } 715 | }, 716 | "autoload": { 717 | "psr-0": { 718 | "Behat\\Gherkin": "src/" 719 | } 720 | }, 721 | "notification-url": "https://packagist.org/downloads/", 722 | "license": [ 723 | "MIT" 724 | ], 725 | "authors": [ 726 | { 727 | "name": "Konstantin Kudryashov", 728 | "email": "ever.zet@gmail.com", 729 | "homepage": "http://everzet.com" 730 | } 731 | ], 732 | "description": "Gherkin DSL parser for PHP 5.3", 733 | "homepage": "http://behat.org/", 734 | "keywords": [ 735 | "BDD", 736 | "Behat", 737 | "Cucumber", 738 | "DSL", 739 | "gherkin", 740 | "parser" 741 | ], 742 | "time": "2016-10-30T11:50:56+00:00" 743 | }, 744 | { 745 | "name": "behat/transliterator", 746 | "version": "v1.1.0", 747 | "source": { 748 | "type": "git", 749 | "url": "https://github.com/Behat/Transliterator.git", 750 | "reference": "868e05be3a9f25ba6424c2dd4849567f50715003" 751 | }, 752 | "dist": { 753 | "type": "zip", 754 | "url": "https://api.github.com/repos/Behat/Transliterator/zipball/868e05be3a9f25ba6424c2dd4849567f50715003", 755 | "reference": "868e05be3a9f25ba6424c2dd4849567f50715003", 756 | "shasum": "" 757 | }, 758 | "require": { 759 | "php": ">=5.3.3" 760 | }, 761 | "type": "library", 762 | "extra": { 763 | "branch-alias": { 764 | "dev-master": "1.1-dev" 765 | } 766 | }, 767 | "autoload": { 768 | "psr-0": { 769 | "Behat\\Transliterator": "src/" 770 | } 771 | }, 772 | "notification-url": "https://packagist.org/downloads/", 773 | "license": [ 774 | "Artistic-1.0" 775 | ], 776 | "description": "String transliterator", 777 | "keywords": [ 778 | "i18n", 779 | "slug", 780 | "transliterator" 781 | ], 782 | "time": "2015-09-28T16:26:35+00:00" 783 | }, 784 | { 785 | "name": "container-interop/container-interop", 786 | "version": "1.2.0", 787 | "source": { 788 | "type": "git", 789 | "url": "https://github.com/container-interop/container-interop.git", 790 | "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" 791 | }, 792 | "dist": { 793 | "type": "zip", 794 | "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", 795 | "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", 796 | "shasum": "" 797 | }, 798 | "require": { 799 | "psr/container": "^1.0" 800 | }, 801 | "type": "library", 802 | "autoload": { 803 | "psr-4": { 804 | "Interop\\Container\\": "src/Interop/Container/" 805 | } 806 | }, 807 | "notification-url": "https://packagist.org/downloads/", 808 | "license": [ 809 | "MIT" 810 | ], 811 | "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", 812 | "homepage": "https://github.com/container-interop/container-interop", 813 | "time": "2017-02-14T19:40:03+00:00" 814 | }, 815 | { 816 | "name": "doctrine/instantiator", 817 | "version": "1.0.5", 818 | "source": { 819 | "type": "git", 820 | "url": "https://github.com/doctrine/instantiator.git", 821 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 822 | }, 823 | "dist": { 824 | "type": "zip", 825 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 826 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 827 | "shasum": "" 828 | }, 829 | "require": { 830 | "php": ">=5.3,<8.0-DEV" 831 | }, 832 | "require-dev": { 833 | "athletic/athletic": "~0.1.8", 834 | "ext-pdo": "*", 835 | "ext-phar": "*", 836 | "phpunit/phpunit": "~4.0", 837 | "squizlabs/php_codesniffer": "~2.0" 838 | }, 839 | "type": "library", 840 | "extra": { 841 | "branch-alias": { 842 | "dev-master": "1.0.x-dev" 843 | } 844 | }, 845 | "autoload": { 846 | "psr-4": { 847 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 848 | } 849 | }, 850 | "notification-url": "https://packagist.org/downloads/", 851 | "license": [ 852 | "MIT" 853 | ], 854 | "authors": [ 855 | { 856 | "name": "Marco Pivetta", 857 | "email": "ocramius@gmail.com", 858 | "homepage": "http://ocramius.github.com/" 859 | } 860 | ], 861 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 862 | "homepage": "https://github.com/doctrine/instantiator", 863 | "keywords": [ 864 | "constructor", 865 | "instantiate" 866 | ], 867 | "time": "2015-06-14T21:17:01+00:00" 868 | }, 869 | { 870 | "name": "myclabs/deep-copy", 871 | "version": "1.6.0", 872 | "source": { 873 | "type": "git", 874 | "url": "https://github.com/myclabs/DeepCopy.git", 875 | "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe" 876 | }, 877 | "dist": { 878 | "type": "zip", 879 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe", 880 | "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe", 881 | "shasum": "" 882 | }, 883 | "require": { 884 | "php": ">=5.4.0" 885 | }, 886 | "require-dev": { 887 | "doctrine/collections": "1.*", 888 | "phpunit/phpunit": "~4.1" 889 | }, 890 | "type": "library", 891 | "autoload": { 892 | "psr-4": { 893 | "DeepCopy\\": "src/DeepCopy/" 894 | } 895 | }, 896 | "notification-url": "https://packagist.org/downloads/", 897 | "license": [ 898 | "MIT" 899 | ], 900 | "description": "Create deep copies (clones) of your objects", 901 | "homepage": "https://github.com/myclabs/DeepCopy", 902 | "keywords": [ 903 | "clone", 904 | "copy", 905 | "duplicate", 906 | "object", 907 | "object graph" 908 | ], 909 | "time": "2017-01-26T22:05:40+00:00" 910 | }, 911 | { 912 | "name": "phpspec/prophecy", 913 | "version": "v1.7.0", 914 | "source": { 915 | "type": "git", 916 | "url": "https://github.com/phpspec/prophecy.git", 917 | "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" 918 | }, 919 | "dist": { 920 | "type": "zip", 921 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", 922 | "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", 923 | "shasum": "" 924 | }, 925 | "require": { 926 | "doctrine/instantiator": "^1.0.2", 927 | "php": "^5.3|^7.0", 928 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", 929 | "sebastian/comparator": "^1.1|^2.0", 930 | "sebastian/recursion-context": "^1.0|^2.0|^3.0" 931 | }, 932 | "require-dev": { 933 | "phpspec/phpspec": "^2.5|^3.2", 934 | "phpunit/phpunit": "^4.8 || ^5.6.5" 935 | }, 936 | "type": "library", 937 | "extra": { 938 | "branch-alias": { 939 | "dev-master": "1.6.x-dev" 940 | } 941 | }, 942 | "autoload": { 943 | "psr-0": { 944 | "Prophecy\\": "src/" 945 | } 946 | }, 947 | "notification-url": "https://packagist.org/downloads/", 948 | "license": [ 949 | "MIT" 950 | ], 951 | "authors": [ 952 | { 953 | "name": "Konstantin Kudryashov", 954 | "email": "ever.zet@gmail.com", 955 | "homepage": "http://everzet.com" 956 | }, 957 | { 958 | "name": "Marcello Duarte", 959 | "email": "marcello.duarte@gmail.com" 960 | } 961 | ], 962 | "description": "Highly opinionated mocking framework for PHP 5.3+", 963 | "homepage": "https://github.com/phpspec/prophecy", 964 | "keywords": [ 965 | "Double", 966 | "Dummy", 967 | "fake", 968 | "mock", 969 | "spy", 970 | "stub" 971 | ], 972 | "time": "2017-03-02T20:05:34+00:00" 973 | }, 974 | { 975 | "name": "phpunit/php-code-coverage", 976 | "version": "4.0.7", 977 | "source": { 978 | "type": "git", 979 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 980 | "reference": "09e2277d14ea467e5a984010f501343ef29ffc69" 981 | }, 982 | "dist": { 983 | "type": "zip", 984 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/09e2277d14ea467e5a984010f501343ef29ffc69", 985 | "reference": "09e2277d14ea467e5a984010f501343ef29ffc69", 986 | "shasum": "" 987 | }, 988 | "require": { 989 | "ext-dom": "*", 990 | "ext-xmlwriter": "*", 991 | "php": "^5.6 || ^7.0", 992 | "phpunit/php-file-iterator": "^1.3", 993 | "phpunit/php-text-template": "^1.2", 994 | "phpunit/php-token-stream": "^1.4.2 || ^2.0", 995 | "sebastian/code-unit-reverse-lookup": "^1.0", 996 | "sebastian/environment": "^1.3.2 || ^2.0", 997 | "sebastian/version": "^1.0 || ^2.0" 998 | }, 999 | "require-dev": { 1000 | "ext-xdebug": "^2.1.4", 1001 | "phpunit/phpunit": "^5.7" 1002 | }, 1003 | "suggest": { 1004 | "ext-xdebug": "^2.5.1" 1005 | }, 1006 | "type": "library", 1007 | "extra": { 1008 | "branch-alias": { 1009 | "dev-master": "4.0.x-dev" 1010 | } 1011 | }, 1012 | "autoload": { 1013 | "classmap": [ 1014 | "src/" 1015 | ] 1016 | }, 1017 | "notification-url": "https://packagist.org/downloads/", 1018 | "license": [ 1019 | "BSD-3-Clause" 1020 | ], 1021 | "authors": [ 1022 | { 1023 | "name": "Sebastian Bergmann", 1024 | "email": "sb@sebastian-bergmann.de", 1025 | "role": "lead" 1026 | } 1027 | ], 1028 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 1029 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 1030 | "keywords": [ 1031 | "coverage", 1032 | "testing", 1033 | "xunit" 1034 | ], 1035 | "time": "2017-03-01T09:12:17+00:00" 1036 | }, 1037 | { 1038 | "name": "phpunit/php-file-iterator", 1039 | "version": "1.4.2", 1040 | "source": { 1041 | "type": "git", 1042 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 1043 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" 1044 | }, 1045 | "dist": { 1046 | "type": "zip", 1047 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", 1048 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", 1049 | "shasum": "" 1050 | }, 1051 | "require": { 1052 | "php": ">=5.3.3" 1053 | }, 1054 | "type": "library", 1055 | "extra": { 1056 | "branch-alias": { 1057 | "dev-master": "1.4.x-dev" 1058 | } 1059 | }, 1060 | "autoload": { 1061 | "classmap": [ 1062 | "src/" 1063 | ] 1064 | }, 1065 | "notification-url": "https://packagist.org/downloads/", 1066 | "license": [ 1067 | "BSD-3-Clause" 1068 | ], 1069 | "authors": [ 1070 | { 1071 | "name": "Sebastian Bergmann", 1072 | "email": "sb@sebastian-bergmann.de", 1073 | "role": "lead" 1074 | } 1075 | ], 1076 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 1077 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 1078 | "keywords": [ 1079 | "filesystem", 1080 | "iterator" 1081 | ], 1082 | "time": "2016-10-03T07:40:28+00:00" 1083 | }, 1084 | { 1085 | "name": "phpunit/php-text-template", 1086 | "version": "1.2.1", 1087 | "source": { 1088 | "type": "git", 1089 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 1090 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 1091 | }, 1092 | "dist": { 1093 | "type": "zip", 1094 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1095 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1096 | "shasum": "" 1097 | }, 1098 | "require": { 1099 | "php": ">=5.3.3" 1100 | }, 1101 | "type": "library", 1102 | "autoload": { 1103 | "classmap": [ 1104 | "src/" 1105 | ] 1106 | }, 1107 | "notification-url": "https://packagist.org/downloads/", 1108 | "license": [ 1109 | "BSD-3-Clause" 1110 | ], 1111 | "authors": [ 1112 | { 1113 | "name": "Sebastian Bergmann", 1114 | "email": "sebastian@phpunit.de", 1115 | "role": "lead" 1116 | } 1117 | ], 1118 | "description": "Simple template engine.", 1119 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 1120 | "keywords": [ 1121 | "template" 1122 | ], 1123 | "time": "2015-06-21T13:50:34+00:00" 1124 | }, 1125 | { 1126 | "name": "phpunit/php-timer", 1127 | "version": "1.0.9", 1128 | "source": { 1129 | "type": "git", 1130 | "url": "https://github.com/sebastianbergmann/php-timer.git", 1131 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" 1132 | }, 1133 | "dist": { 1134 | "type": "zip", 1135 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 1136 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 1137 | "shasum": "" 1138 | }, 1139 | "require": { 1140 | "php": "^5.3.3 || ^7.0" 1141 | }, 1142 | "require-dev": { 1143 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 1144 | }, 1145 | "type": "library", 1146 | "extra": { 1147 | "branch-alias": { 1148 | "dev-master": "1.0-dev" 1149 | } 1150 | }, 1151 | "autoload": { 1152 | "classmap": [ 1153 | "src/" 1154 | ] 1155 | }, 1156 | "notification-url": "https://packagist.org/downloads/", 1157 | "license": [ 1158 | "BSD-3-Clause" 1159 | ], 1160 | "authors": [ 1161 | { 1162 | "name": "Sebastian Bergmann", 1163 | "email": "sb@sebastian-bergmann.de", 1164 | "role": "lead" 1165 | } 1166 | ], 1167 | "description": "Utility class for timing", 1168 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 1169 | "keywords": [ 1170 | "timer" 1171 | ], 1172 | "time": "2017-02-26T11:10:40+00:00" 1173 | }, 1174 | { 1175 | "name": "phpunit/php-token-stream", 1176 | "version": "1.4.11", 1177 | "source": { 1178 | "type": "git", 1179 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 1180 | "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" 1181 | }, 1182 | "dist": { 1183 | "type": "zip", 1184 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", 1185 | "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", 1186 | "shasum": "" 1187 | }, 1188 | "require": { 1189 | "ext-tokenizer": "*", 1190 | "php": ">=5.3.3" 1191 | }, 1192 | "require-dev": { 1193 | "phpunit/phpunit": "~4.2" 1194 | }, 1195 | "type": "library", 1196 | "extra": { 1197 | "branch-alias": { 1198 | "dev-master": "1.4-dev" 1199 | } 1200 | }, 1201 | "autoload": { 1202 | "classmap": [ 1203 | "src/" 1204 | ] 1205 | }, 1206 | "notification-url": "https://packagist.org/downloads/", 1207 | "license": [ 1208 | "BSD-3-Clause" 1209 | ], 1210 | "authors": [ 1211 | { 1212 | "name": "Sebastian Bergmann", 1213 | "email": "sebastian@phpunit.de" 1214 | } 1215 | ], 1216 | "description": "Wrapper around PHP's tokenizer extension.", 1217 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 1218 | "keywords": [ 1219 | "tokenizer" 1220 | ], 1221 | "time": "2017-02-27T10:12:30+00:00" 1222 | }, 1223 | { 1224 | "name": "phpunit/phpunit", 1225 | "version": "5.7.16", 1226 | "source": { 1227 | "type": "git", 1228 | "url": "https://github.com/sebastianbergmann/phpunit.git", 1229 | "reference": "dafc78e2a7d12139b0e97078d1082326bd09363d" 1230 | }, 1231 | "dist": { 1232 | "type": "zip", 1233 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/dafc78e2a7d12139b0e97078d1082326bd09363d", 1234 | "reference": "dafc78e2a7d12139b0e97078d1082326bd09363d", 1235 | "shasum": "" 1236 | }, 1237 | "require": { 1238 | "ext-dom": "*", 1239 | "ext-json": "*", 1240 | "ext-libxml": "*", 1241 | "ext-mbstring": "*", 1242 | "ext-xml": "*", 1243 | "myclabs/deep-copy": "~1.3", 1244 | "php": "^5.6 || ^7.0", 1245 | "phpspec/prophecy": "^1.6.2", 1246 | "phpunit/php-code-coverage": "^4.0.4", 1247 | "phpunit/php-file-iterator": "~1.4", 1248 | "phpunit/php-text-template": "~1.2", 1249 | "phpunit/php-timer": "^1.0.6", 1250 | "phpunit/phpunit-mock-objects": "^3.2", 1251 | "sebastian/comparator": "^1.2.4", 1252 | "sebastian/diff": "~1.2", 1253 | "sebastian/environment": "^1.3.4 || ^2.0", 1254 | "sebastian/exporter": "~2.0", 1255 | "sebastian/global-state": "^1.1", 1256 | "sebastian/object-enumerator": "~2.0", 1257 | "sebastian/resource-operations": "~1.0", 1258 | "sebastian/version": "~1.0.3|~2.0", 1259 | "symfony/yaml": "~2.1|~3.0" 1260 | }, 1261 | "conflict": { 1262 | "phpdocumentor/reflection-docblock": "3.0.2" 1263 | }, 1264 | "require-dev": { 1265 | "ext-pdo": "*" 1266 | }, 1267 | "suggest": { 1268 | "ext-xdebug": "*", 1269 | "phpunit/php-invoker": "~1.1" 1270 | }, 1271 | "bin": [ 1272 | "phpunit" 1273 | ], 1274 | "type": "library", 1275 | "extra": { 1276 | "branch-alias": { 1277 | "dev-master": "5.7.x-dev" 1278 | } 1279 | }, 1280 | "autoload": { 1281 | "classmap": [ 1282 | "src/" 1283 | ] 1284 | }, 1285 | "notification-url": "https://packagist.org/downloads/", 1286 | "license": [ 1287 | "BSD-3-Clause" 1288 | ], 1289 | "authors": [ 1290 | { 1291 | "name": "Sebastian Bergmann", 1292 | "email": "sebastian@phpunit.de", 1293 | "role": "lead" 1294 | } 1295 | ], 1296 | "description": "The PHP Unit Testing framework.", 1297 | "homepage": "https://phpunit.de/", 1298 | "keywords": [ 1299 | "phpunit", 1300 | "testing", 1301 | "xunit" 1302 | ], 1303 | "time": "2017-03-15T13:02:34+00:00" 1304 | }, 1305 | { 1306 | "name": "phpunit/phpunit-mock-objects", 1307 | "version": "3.4.3", 1308 | "source": { 1309 | "type": "git", 1310 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 1311 | "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24" 1312 | }, 1313 | "dist": { 1314 | "type": "zip", 1315 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", 1316 | "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", 1317 | "shasum": "" 1318 | }, 1319 | "require": { 1320 | "doctrine/instantiator": "^1.0.2", 1321 | "php": "^5.6 || ^7.0", 1322 | "phpunit/php-text-template": "^1.2", 1323 | "sebastian/exporter": "^1.2 || ^2.0" 1324 | }, 1325 | "conflict": { 1326 | "phpunit/phpunit": "<5.4.0" 1327 | }, 1328 | "require-dev": { 1329 | "phpunit/phpunit": "^5.4" 1330 | }, 1331 | "suggest": { 1332 | "ext-soap": "*" 1333 | }, 1334 | "type": "library", 1335 | "extra": { 1336 | "branch-alias": { 1337 | "dev-master": "3.2.x-dev" 1338 | } 1339 | }, 1340 | "autoload": { 1341 | "classmap": [ 1342 | "src/" 1343 | ] 1344 | }, 1345 | "notification-url": "https://packagist.org/downloads/", 1346 | "license": [ 1347 | "BSD-3-Clause" 1348 | ], 1349 | "authors": [ 1350 | { 1351 | "name": "Sebastian Bergmann", 1352 | "email": "sb@sebastian-bergmann.de", 1353 | "role": "lead" 1354 | } 1355 | ], 1356 | "description": "Mock Object library for PHPUnit", 1357 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1358 | "keywords": [ 1359 | "mock", 1360 | "xunit" 1361 | ], 1362 | "time": "2016-12-08T20:27:08+00:00" 1363 | }, 1364 | { 1365 | "name": "psr/container", 1366 | "version": "1.0.0", 1367 | "source": { 1368 | "type": "git", 1369 | "url": "https://github.com/php-fig/container.git", 1370 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" 1371 | }, 1372 | "dist": { 1373 | "type": "zip", 1374 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 1375 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 1376 | "shasum": "" 1377 | }, 1378 | "require": { 1379 | "php": ">=5.3.0" 1380 | }, 1381 | "type": "library", 1382 | "extra": { 1383 | "branch-alias": { 1384 | "dev-master": "1.0.x-dev" 1385 | } 1386 | }, 1387 | "autoload": { 1388 | "psr-4": { 1389 | "Psr\\Container\\": "src/" 1390 | } 1391 | }, 1392 | "notification-url": "https://packagist.org/downloads/", 1393 | "license": [ 1394 | "MIT" 1395 | ], 1396 | "authors": [ 1397 | { 1398 | "name": "PHP-FIG", 1399 | "homepage": "http://www.php-fig.org/" 1400 | } 1401 | ], 1402 | "description": "Common Container Interface (PHP FIG PSR-11)", 1403 | "homepage": "https://github.com/php-fig/container", 1404 | "keywords": [ 1405 | "PSR-11", 1406 | "container", 1407 | "container-interface", 1408 | "container-interop", 1409 | "psr" 1410 | ], 1411 | "time": "2017-02-14T16:28:37+00:00" 1412 | }, 1413 | { 1414 | "name": "psr/log", 1415 | "version": "1.0.2", 1416 | "source": { 1417 | "type": "git", 1418 | "url": "https://github.com/php-fig/log.git", 1419 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" 1420 | }, 1421 | "dist": { 1422 | "type": "zip", 1423 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 1424 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 1425 | "shasum": "" 1426 | }, 1427 | "require": { 1428 | "php": ">=5.3.0" 1429 | }, 1430 | "type": "library", 1431 | "extra": { 1432 | "branch-alias": { 1433 | "dev-master": "1.0.x-dev" 1434 | } 1435 | }, 1436 | "autoload": { 1437 | "psr-4": { 1438 | "Psr\\Log\\": "Psr/Log/" 1439 | } 1440 | }, 1441 | "notification-url": "https://packagist.org/downloads/", 1442 | "license": [ 1443 | "MIT" 1444 | ], 1445 | "authors": [ 1446 | { 1447 | "name": "PHP-FIG", 1448 | "homepage": "http://www.php-fig.org/" 1449 | } 1450 | ], 1451 | "description": "Common interface for logging libraries", 1452 | "homepage": "https://github.com/php-fig/log", 1453 | "keywords": [ 1454 | "log", 1455 | "psr", 1456 | "psr-3" 1457 | ], 1458 | "time": "2016-10-10T12:19:37+00:00" 1459 | }, 1460 | { 1461 | "name": "sebastian/code-unit-reverse-lookup", 1462 | "version": "1.0.1", 1463 | "source": { 1464 | "type": "git", 1465 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 1466 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" 1467 | }, 1468 | "dist": { 1469 | "type": "zip", 1470 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 1471 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 1472 | "shasum": "" 1473 | }, 1474 | "require": { 1475 | "php": "^5.6 || ^7.0" 1476 | }, 1477 | "require-dev": { 1478 | "phpunit/phpunit": "^5.7 || ^6.0" 1479 | }, 1480 | "type": "library", 1481 | "extra": { 1482 | "branch-alias": { 1483 | "dev-master": "1.0.x-dev" 1484 | } 1485 | }, 1486 | "autoload": { 1487 | "classmap": [ 1488 | "src/" 1489 | ] 1490 | }, 1491 | "notification-url": "https://packagist.org/downloads/", 1492 | "license": [ 1493 | "BSD-3-Clause" 1494 | ], 1495 | "authors": [ 1496 | { 1497 | "name": "Sebastian Bergmann", 1498 | "email": "sebastian@phpunit.de" 1499 | } 1500 | ], 1501 | "description": "Looks up which function or method a line of code belongs to", 1502 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 1503 | "time": "2017-03-04T06:30:41+00:00" 1504 | }, 1505 | { 1506 | "name": "sebastian/comparator", 1507 | "version": "1.2.4", 1508 | "source": { 1509 | "type": "git", 1510 | "url": "https://github.com/sebastianbergmann/comparator.git", 1511 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" 1512 | }, 1513 | "dist": { 1514 | "type": "zip", 1515 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 1516 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 1517 | "shasum": "" 1518 | }, 1519 | "require": { 1520 | "php": ">=5.3.3", 1521 | "sebastian/diff": "~1.2", 1522 | "sebastian/exporter": "~1.2 || ~2.0" 1523 | }, 1524 | "require-dev": { 1525 | "phpunit/phpunit": "~4.4" 1526 | }, 1527 | "type": "library", 1528 | "extra": { 1529 | "branch-alias": { 1530 | "dev-master": "1.2.x-dev" 1531 | } 1532 | }, 1533 | "autoload": { 1534 | "classmap": [ 1535 | "src/" 1536 | ] 1537 | }, 1538 | "notification-url": "https://packagist.org/downloads/", 1539 | "license": [ 1540 | "BSD-3-Clause" 1541 | ], 1542 | "authors": [ 1543 | { 1544 | "name": "Jeff Welch", 1545 | "email": "whatthejeff@gmail.com" 1546 | }, 1547 | { 1548 | "name": "Volker Dusch", 1549 | "email": "github@wallbash.com" 1550 | }, 1551 | { 1552 | "name": "Bernhard Schussek", 1553 | "email": "bschussek@2bepublished.at" 1554 | }, 1555 | { 1556 | "name": "Sebastian Bergmann", 1557 | "email": "sebastian@phpunit.de" 1558 | } 1559 | ], 1560 | "description": "Provides the functionality to compare PHP values for equality", 1561 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1562 | "keywords": [ 1563 | "comparator", 1564 | "compare", 1565 | "equality" 1566 | ], 1567 | "time": "2017-01-29T09:50:25+00:00" 1568 | }, 1569 | { 1570 | "name": "sebastian/diff", 1571 | "version": "1.4.1", 1572 | "source": { 1573 | "type": "git", 1574 | "url": "https://github.com/sebastianbergmann/diff.git", 1575 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" 1576 | }, 1577 | "dist": { 1578 | "type": "zip", 1579 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", 1580 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", 1581 | "shasum": "" 1582 | }, 1583 | "require": { 1584 | "php": ">=5.3.3" 1585 | }, 1586 | "require-dev": { 1587 | "phpunit/phpunit": "~4.8" 1588 | }, 1589 | "type": "library", 1590 | "extra": { 1591 | "branch-alias": { 1592 | "dev-master": "1.4-dev" 1593 | } 1594 | }, 1595 | "autoload": { 1596 | "classmap": [ 1597 | "src/" 1598 | ] 1599 | }, 1600 | "notification-url": "https://packagist.org/downloads/", 1601 | "license": [ 1602 | "BSD-3-Clause" 1603 | ], 1604 | "authors": [ 1605 | { 1606 | "name": "Kore Nordmann", 1607 | "email": "mail@kore-nordmann.de" 1608 | }, 1609 | { 1610 | "name": "Sebastian Bergmann", 1611 | "email": "sebastian@phpunit.de" 1612 | } 1613 | ], 1614 | "description": "Diff implementation", 1615 | "homepage": "https://github.com/sebastianbergmann/diff", 1616 | "keywords": [ 1617 | "diff" 1618 | ], 1619 | "time": "2015-12-08T07:14:41+00:00" 1620 | }, 1621 | { 1622 | "name": "sebastian/environment", 1623 | "version": "2.0.0", 1624 | "source": { 1625 | "type": "git", 1626 | "url": "https://github.com/sebastianbergmann/environment.git", 1627 | "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" 1628 | }, 1629 | "dist": { 1630 | "type": "zip", 1631 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", 1632 | "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", 1633 | "shasum": "" 1634 | }, 1635 | "require": { 1636 | "php": "^5.6 || ^7.0" 1637 | }, 1638 | "require-dev": { 1639 | "phpunit/phpunit": "^5.0" 1640 | }, 1641 | "type": "library", 1642 | "extra": { 1643 | "branch-alias": { 1644 | "dev-master": "2.0.x-dev" 1645 | } 1646 | }, 1647 | "autoload": { 1648 | "classmap": [ 1649 | "src/" 1650 | ] 1651 | }, 1652 | "notification-url": "https://packagist.org/downloads/", 1653 | "license": [ 1654 | "BSD-3-Clause" 1655 | ], 1656 | "authors": [ 1657 | { 1658 | "name": "Sebastian Bergmann", 1659 | "email": "sebastian@phpunit.de" 1660 | } 1661 | ], 1662 | "description": "Provides functionality to handle HHVM/PHP environments", 1663 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1664 | "keywords": [ 1665 | "Xdebug", 1666 | "environment", 1667 | "hhvm" 1668 | ], 1669 | "time": "2016-11-26T07:53:53+00:00" 1670 | }, 1671 | { 1672 | "name": "sebastian/exporter", 1673 | "version": "2.0.0", 1674 | "source": { 1675 | "type": "git", 1676 | "url": "https://github.com/sebastianbergmann/exporter.git", 1677 | "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" 1678 | }, 1679 | "dist": { 1680 | "type": "zip", 1681 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", 1682 | "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", 1683 | "shasum": "" 1684 | }, 1685 | "require": { 1686 | "php": ">=5.3.3", 1687 | "sebastian/recursion-context": "~2.0" 1688 | }, 1689 | "require-dev": { 1690 | "ext-mbstring": "*", 1691 | "phpunit/phpunit": "~4.4" 1692 | }, 1693 | "type": "library", 1694 | "extra": { 1695 | "branch-alias": { 1696 | "dev-master": "2.0.x-dev" 1697 | } 1698 | }, 1699 | "autoload": { 1700 | "classmap": [ 1701 | "src/" 1702 | ] 1703 | }, 1704 | "notification-url": "https://packagist.org/downloads/", 1705 | "license": [ 1706 | "BSD-3-Clause" 1707 | ], 1708 | "authors": [ 1709 | { 1710 | "name": "Jeff Welch", 1711 | "email": "whatthejeff@gmail.com" 1712 | }, 1713 | { 1714 | "name": "Volker Dusch", 1715 | "email": "github@wallbash.com" 1716 | }, 1717 | { 1718 | "name": "Bernhard Schussek", 1719 | "email": "bschussek@2bepublished.at" 1720 | }, 1721 | { 1722 | "name": "Sebastian Bergmann", 1723 | "email": "sebastian@phpunit.de" 1724 | }, 1725 | { 1726 | "name": "Adam Harvey", 1727 | "email": "aharvey@php.net" 1728 | } 1729 | ], 1730 | "description": "Provides the functionality to export PHP variables for visualization", 1731 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1732 | "keywords": [ 1733 | "export", 1734 | "exporter" 1735 | ], 1736 | "time": "2016-11-19T08:54:04+00:00" 1737 | }, 1738 | { 1739 | "name": "sebastian/global-state", 1740 | "version": "1.1.1", 1741 | "source": { 1742 | "type": "git", 1743 | "url": "https://github.com/sebastianbergmann/global-state.git", 1744 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1745 | }, 1746 | "dist": { 1747 | "type": "zip", 1748 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1749 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1750 | "shasum": "" 1751 | }, 1752 | "require": { 1753 | "php": ">=5.3.3" 1754 | }, 1755 | "require-dev": { 1756 | "phpunit/phpunit": "~4.2" 1757 | }, 1758 | "suggest": { 1759 | "ext-uopz": "*" 1760 | }, 1761 | "type": "library", 1762 | "extra": { 1763 | "branch-alias": { 1764 | "dev-master": "1.0-dev" 1765 | } 1766 | }, 1767 | "autoload": { 1768 | "classmap": [ 1769 | "src/" 1770 | ] 1771 | }, 1772 | "notification-url": "https://packagist.org/downloads/", 1773 | "license": [ 1774 | "BSD-3-Clause" 1775 | ], 1776 | "authors": [ 1777 | { 1778 | "name": "Sebastian Bergmann", 1779 | "email": "sebastian@phpunit.de" 1780 | } 1781 | ], 1782 | "description": "Snapshotting of global state", 1783 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1784 | "keywords": [ 1785 | "global state" 1786 | ], 1787 | "time": "2015-10-12T03:26:01+00:00" 1788 | }, 1789 | { 1790 | "name": "sebastian/object-enumerator", 1791 | "version": "2.0.1", 1792 | "source": { 1793 | "type": "git", 1794 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1795 | "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" 1796 | }, 1797 | "dist": { 1798 | "type": "zip", 1799 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", 1800 | "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", 1801 | "shasum": "" 1802 | }, 1803 | "require": { 1804 | "php": ">=5.6", 1805 | "sebastian/recursion-context": "~2.0" 1806 | }, 1807 | "require-dev": { 1808 | "phpunit/phpunit": "~5" 1809 | }, 1810 | "type": "library", 1811 | "extra": { 1812 | "branch-alias": { 1813 | "dev-master": "2.0.x-dev" 1814 | } 1815 | }, 1816 | "autoload": { 1817 | "classmap": [ 1818 | "src/" 1819 | ] 1820 | }, 1821 | "notification-url": "https://packagist.org/downloads/", 1822 | "license": [ 1823 | "BSD-3-Clause" 1824 | ], 1825 | "authors": [ 1826 | { 1827 | "name": "Sebastian Bergmann", 1828 | "email": "sebastian@phpunit.de" 1829 | } 1830 | ], 1831 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1832 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1833 | "time": "2017-02-18T15:18:39+00:00" 1834 | }, 1835 | { 1836 | "name": "sebastian/recursion-context", 1837 | "version": "2.0.0", 1838 | "source": { 1839 | "type": "git", 1840 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1841 | "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" 1842 | }, 1843 | "dist": { 1844 | "type": "zip", 1845 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", 1846 | "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", 1847 | "shasum": "" 1848 | }, 1849 | "require": { 1850 | "php": ">=5.3.3" 1851 | }, 1852 | "require-dev": { 1853 | "phpunit/phpunit": "~4.4" 1854 | }, 1855 | "type": "library", 1856 | "extra": { 1857 | "branch-alias": { 1858 | "dev-master": "2.0.x-dev" 1859 | } 1860 | }, 1861 | "autoload": { 1862 | "classmap": [ 1863 | "src/" 1864 | ] 1865 | }, 1866 | "notification-url": "https://packagist.org/downloads/", 1867 | "license": [ 1868 | "BSD-3-Clause" 1869 | ], 1870 | "authors": [ 1871 | { 1872 | "name": "Jeff Welch", 1873 | "email": "whatthejeff@gmail.com" 1874 | }, 1875 | { 1876 | "name": "Sebastian Bergmann", 1877 | "email": "sebastian@phpunit.de" 1878 | }, 1879 | { 1880 | "name": "Adam Harvey", 1881 | "email": "aharvey@php.net" 1882 | } 1883 | ], 1884 | "description": "Provides functionality to recursively process PHP variables", 1885 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1886 | "time": "2016-11-19T07:33:16+00:00" 1887 | }, 1888 | { 1889 | "name": "sebastian/resource-operations", 1890 | "version": "1.0.0", 1891 | "source": { 1892 | "type": "git", 1893 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1894 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 1895 | }, 1896 | "dist": { 1897 | "type": "zip", 1898 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1899 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1900 | "shasum": "" 1901 | }, 1902 | "require": { 1903 | "php": ">=5.6.0" 1904 | }, 1905 | "type": "library", 1906 | "extra": { 1907 | "branch-alias": { 1908 | "dev-master": "1.0.x-dev" 1909 | } 1910 | }, 1911 | "autoload": { 1912 | "classmap": [ 1913 | "src/" 1914 | ] 1915 | }, 1916 | "notification-url": "https://packagist.org/downloads/", 1917 | "license": [ 1918 | "BSD-3-Clause" 1919 | ], 1920 | "authors": [ 1921 | { 1922 | "name": "Sebastian Bergmann", 1923 | "email": "sebastian@phpunit.de" 1924 | } 1925 | ], 1926 | "description": "Provides a list of PHP built-in functions that operate on resources", 1927 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1928 | "time": "2015-07-28T20:34:47+00:00" 1929 | }, 1930 | { 1931 | "name": "sebastian/version", 1932 | "version": "2.0.1", 1933 | "source": { 1934 | "type": "git", 1935 | "url": "https://github.com/sebastianbergmann/version.git", 1936 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" 1937 | }, 1938 | "dist": { 1939 | "type": "zip", 1940 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", 1941 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", 1942 | "shasum": "" 1943 | }, 1944 | "require": { 1945 | "php": ">=5.6" 1946 | }, 1947 | "type": "library", 1948 | "extra": { 1949 | "branch-alias": { 1950 | "dev-master": "2.0.x-dev" 1951 | } 1952 | }, 1953 | "autoload": { 1954 | "classmap": [ 1955 | "src/" 1956 | ] 1957 | }, 1958 | "notification-url": "https://packagist.org/downloads/", 1959 | "license": [ 1960 | "BSD-3-Clause" 1961 | ], 1962 | "authors": [ 1963 | { 1964 | "name": "Sebastian Bergmann", 1965 | "email": "sebastian@phpunit.de", 1966 | "role": "lead" 1967 | } 1968 | ], 1969 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1970 | "homepage": "https://github.com/sebastianbergmann/version", 1971 | "time": "2016-10-03T07:35:21+00:00" 1972 | }, 1973 | { 1974 | "name": "symfony/class-loader", 1975 | "version": "v3.2.6", 1976 | "source": { 1977 | "type": "git", 1978 | "url": "https://github.com/symfony/class-loader.git", 1979 | "reference": "c29a5bc6ca14cfff1f5e3d7781ed74b6e898d2b9" 1980 | }, 1981 | "dist": { 1982 | "type": "zip", 1983 | "url": "https://api.github.com/repos/symfony/class-loader/zipball/c29a5bc6ca14cfff1f5e3d7781ed74b6e898d2b9", 1984 | "reference": "c29a5bc6ca14cfff1f5e3d7781ed74b6e898d2b9", 1985 | "shasum": "" 1986 | }, 1987 | "require": { 1988 | "php": ">=5.5.9" 1989 | }, 1990 | "require-dev": { 1991 | "symfony/finder": "~2.8|~3.0", 1992 | "symfony/polyfill-apcu": "~1.1" 1993 | }, 1994 | "suggest": { 1995 | "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM" 1996 | }, 1997 | "type": "library", 1998 | "extra": { 1999 | "branch-alias": { 2000 | "dev-master": "3.2-dev" 2001 | } 2002 | }, 2003 | "autoload": { 2004 | "psr-4": { 2005 | "Symfony\\Component\\ClassLoader\\": "" 2006 | }, 2007 | "exclude-from-classmap": [ 2008 | "/Tests/" 2009 | ] 2010 | }, 2011 | "notification-url": "https://packagist.org/downloads/", 2012 | "license": [ 2013 | "MIT" 2014 | ], 2015 | "authors": [ 2016 | { 2017 | "name": "Fabien Potencier", 2018 | "email": "fabien@symfony.com" 2019 | }, 2020 | { 2021 | "name": "Symfony Community", 2022 | "homepage": "https://symfony.com/contributors" 2023 | } 2024 | ], 2025 | "description": "Symfony ClassLoader Component", 2026 | "homepage": "https://symfony.com", 2027 | "time": "2017-02-18T17:28:00+00:00" 2028 | }, 2029 | { 2030 | "name": "symfony/config", 2031 | "version": "v3.2.6", 2032 | "source": { 2033 | "type": "git", 2034 | "url": "https://github.com/symfony/config.git", 2035 | "reference": "741d6d4cd1414d67d48eb71aba6072b46ba740c2" 2036 | }, 2037 | "dist": { 2038 | "type": "zip", 2039 | "url": "https://api.github.com/repos/symfony/config/zipball/741d6d4cd1414d67d48eb71aba6072b46ba740c2", 2040 | "reference": "741d6d4cd1414d67d48eb71aba6072b46ba740c2", 2041 | "shasum": "" 2042 | }, 2043 | "require": { 2044 | "php": ">=5.5.9", 2045 | "symfony/filesystem": "~2.8|~3.0" 2046 | }, 2047 | "require-dev": { 2048 | "symfony/yaml": "~3.0" 2049 | }, 2050 | "suggest": { 2051 | "symfony/yaml": "To use the yaml reference dumper" 2052 | }, 2053 | "type": "library", 2054 | "extra": { 2055 | "branch-alias": { 2056 | "dev-master": "3.2-dev" 2057 | } 2058 | }, 2059 | "autoload": { 2060 | "psr-4": { 2061 | "Symfony\\Component\\Config\\": "" 2062 | }, 2063 | "exclude-from-classmap": [ 2064 | "/Tests/" 2065 | ] 2066 | }, 2067 | "notification-url": "https://packagist.org/downloads/", 2068 | "license": [ 2069 | "MIT" 2070 | ], 2071 | "authors": [ 2072 | { 2073 | "name": "Fabien Potencier", 2074 | "email": "fabien@symfony.com" 2075 | }, 2076 | { 2077 | "name": "Symfony Community", 2078 | "homepage": "https://symfony.com/contributors" 2079 | } 2080 | ], 2081 | "description": "Symfony Config Component", 2082 | "homepage": "https://symfony.com", 2083 | "time": "2017-03-01T18:18:25+00:00" 2084 | }, 2085 | { 2086 | "name": "symfony/console", 2087 | "version": "v3.2.6", 2088 | "source": { 2089 | "type": "git", 2090 | "url": "https://github.com/symfony/console.git", 2091 | "reference": "28fb243a2b5727774ca309ec2d92da240f1af0dd" 2092 | }, 2093 | "dist": { 2094 | "type": "zip", 2095 | "url": "https://api.github.com/repos/symfony/console/zipball/28fb243a2b5727774ca309ec2d92da240f1af0dd", 2096 | "reference": "28fb243a2b5727774ca309ec2d92da240f1af0dd", 2097 | "shasum": "" 2098 | }, 2099 | "require": { 2100 | "php": ">=5.5.9", 2101 | "symfony/debug": "~2.8|~3.0", 2102 | "symfony/polyfill-mbstring": "~1.0" 2103 | }, 2104 | "require-dev": { 2105 | "psr/log": "~1.0", 2106 | "symfony/event-dispatcher": "~2.8|~3.0", 2107 | "symfony/filesystem": "~2.8|~3.0", 2108 | "symfony/process": "~2.8|~3.0" 2109 | }, 2110 | "suggest": { 2111 | "psr/log": "For using the console logger", 2112 | "symfony/event-dispatcher": "", 2113 | "symfony/filesystem": "", 2114 | "symfony/process": "" 2115 | }, 2116 | "type": "library", 2117 | "extra": { 2118 | "branch-alias": { 2119 | "dev-master": "3.2-dev" 2120 | } 2121 | }, 2122 | "autoload": { 2123 | "psr-4": { 2124 | "Symfony\\Component\\Console\\": "" 2125 | }, 2126 | "exclude-from-classmap": [ 2127 | "/Tests/" 2128 | ] 2129 | }, 2130 | "notification-url": "https://packagist.org/downloads/", 2131 | "license": [ 2132 | "MIT" 2133 | ], 2134 | "authors": [ 2135 | { 2136 | "name": "Fabien Potencier", 2137 | "email": "fabien@symfony.com" 2138 | }, 2139 | { 2140 | "name": "Symfony Community", 2141 | "homepage": "https://symfony.com/contributors" 2142 | } 2143 | ], 2144 | "description": "Symfony Console Component", 2145 | "homepage": "https://symfony.com", 2146 | "time": "2017-03-06T19:30:27+00:00" 2147 | }, 2148 | { 2149 | "name": "symfony/debug", 2150 | "version": "v3.2.6", 2151 | "source": { 2152 | "type": "git", 2153 | "url": "https://github.com/symfony/debug.git", 2154 | "reference": "b90c9f91ad8ac37d9f114e369042d3226b34dc1a" 2155 | }, 2156 | "dist": { 2157 | "type": "zip", 2158 | "url": "https://api.github.com/repos/symfony/debug/zipball/b90c9f91ad8ac37d9f114e369042d3226b34dc1a", 2159 | "reference": "b90c9f91ad8ac37d9f114e369042d3226b34dc1a", 2160 | "shasum": "" 2161 | }, 2162 | "require": { 2163 | "php": ">=5.5.9", 2164 | "psr/log": "~1.0" 2165 | }, 2166 | "conflict": { 2167 | "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" 2168 | }, 2169 | "require-dev": { 2170 | "symfony/class-loader": "~2.8|~3.0", 2171 | "symfony/http-kernel": "~2.8|~3.0" 2172 | }, 2173 | "type": "library", 2174 | "extra": { 2175 | "branch-alias": { 2176 | "dev-master": "3.2-dev" 2177 | } 2178 | }, 2179 | "autoload": { 2180 | "psr-4": { 2181 | "Symfony\\Component\\Debug\\": "" 2182 | }, 2183 | "exclude-from-classmap": [ 2184 | "/Tests/" 2185 | ] 2186 | }, 2187 | "notification-url": "https://packagist.org/downloads/", 2188 | "license": [ 2189 | "MIT" 2190 | ], 2191 | "authors": [ 2192 | { 2193 | "name": "Fabien Potencier", 2194 | "email": "fabien@symfony.com" 2195 | }, 2196 | { 2197 | "name": "Symfony Community", 2198 | "homepage": "https://symfony.com/contributors" 2199 | } 2200 | ], 2201 | "description": "Symfony Debug Component", 2202 | "homepage": "https://symfony.com", 2203 | "time": "2017-02-18T17:28:00+00:00" 2204 | }, 2205 | { 2206 | "name": "symfony/dependency-injection", 2207 | "version": "v3.2.6", 2208 | "source": { 2209 | "type": "git", 2210 | "url": "https://github.com/symfony/dependency-injection.git", 2211 | "reference": "74e0935e414ad33d5e82074212c0eedb4681a691" 2212 | }, 2213 | "dist": { 2214 | "type": "zip", 2215 | "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/74e0935e414ad33d5e82074212c0eedb4681a691", 2216 | "reference": "74e0935e414ad33d5e82074212c0eedb4681a691", 2217 | "shasum": "" 2218 | }, 2219 | "require": { 2220 | "php": ">=5.5.9" 2221 | }, 2222 | "conflict": { 2223 | "symfony/yaml": "<3.2" 2224 | }, 2225 | "require-dev": { 2226 | "symfony/config": "~2.8|~3.0", 2227 | "symfony/expression-language": "~2.8|~3.0", 2228 | "symfony/yaml": "~3.2" 2229 | }, 2230 | "suggest": { 2231 | "symfony/config": "", 2232 | "symfony/expression-language": "For using expressions in service container configuration", 2233 | "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", 2234 | "symfony/yaml": "" 2235 | }, 2236 | "type": "library", 2237 | "extra": { 2238 | "branch-alias": { 2239 | "dev-master": "3.2-dev" 2240 | } 2241 | }, 2242 | "autoload": { 2243 | "psr-4": { 2244 | "Symfony\\Component\\DependencyInjection\\": "" 2245 | }, 2246 | "exclude-from-classmap": [ 2247 | "/Tests/" 2248 | ] 2249 | }, 2250 | "notification-url": "https://packagist.org/downloads/", 2251 | "license": [ 2252 | "MIT" 2253 | ], 2254 | "authors": [ 2255 | { 2256 | "name": "Fabien Potencier", 2257 | "email": "fabien@symfony.com" 2258 | }, 2259 | { 2260 | "name": "Symfony Community", 2261 | "homepage": "https://symfony.com/contributors" 2262 | } 2263 | ], 2264 | "description": "Symfony DependencyInjection Component", 2265 | "homepage": "https://symfony.com", 2266 | "time": "2017-03-05T00:06:55+00:00" 2267 | }, 2268 | { 2269 | "name": "symfony/event-dispatcher", 2270 | "version": "v3.2.6", 2271 | "source": { 2272 | "type": "git", 2273 | "url": "https://github.com/symfony/event-dispatcher.git", 2274 | "reference": "b7a1b9e0a0f623ce43b4c8d775eb138f190c9d8d" 2275 | }, 2276 | "dist": { 2277 | "type": "zip", 2278 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7a1b9e0a0f623ce43b4c8d775eb138f190c9d8d", 2279 | "reference": "b7a1b9e0a0f623ce43b4c8d775eb138f190c9d8d", 2280 | "shasum": "" 2281 | }, 2282 | "require": { 2283 | "php": ">=5.5.9" 2284 | }, 2285 | "require-dev": { 2286 | "psr/log": "~1.0", 2287 | "symfony/config": "~2.8|~3.0", 2288 | "symfony/dependency-injection": "~2.8|~3.0", 2289 | "symfony/expression-language": "~2.8|~3.0", 2290 | "symfony/stopwatch": "~2.8|~3.0" 2291 | }, 2292 | "suggest": { 2293 | "symfony/dependency-injection": "", 2294 | "symfony/http-kernel": "" 2295 | }, 2296 | "type": "library", 2297 | "extra": { 2298 | "branch-alias": { 2299 | "dev-master": "3.2-dev" 2300 | } 2301 | }, 2302 | "autoload": { 2303 | "psr-4": { 2304 | "Symfony\\Component\\EventDispatcher\\": "" 2305 | }, 2306 | "exclude-from-classmap": [ 2307 | "/Tests/" 2308 | ] 2309 | }, 2310 | "notification-url": "https://packagist.org/downloads/", 2311 | "license": [ 2312 | "MIT" 2313 | ], 2314 | "authors": [ 2315 | { 2316 | "name": "Fabien Potencier", 2317 | "email": "fabien@symfony.com" 2318 | }, 2319 | { 2320 | "name": "Symfony Community", 2321 | "homepage": "https://symfony.com/contributors" 2322 | } 2323 | ], 2324 | "description": "Symfony EventDispatcher Component", 2325 | "homepage": "https://symfony.com", 2326 | "time": "2017-02-21T09:12:04+00:00" 2327 | }, 2328 | { 2329 | "name": "symfony/filesystem", 2330 | "version": "v3.2.6", 2331 | "source": { 2332 | "type": "git", 2333 | "url": "https://github.com/symfony/filesystem.git", 2334 | "reference": "bc0f17bed914df2cceb989972c3b996043c4da4a" 2335 | }, 2336 | "dist": { 2337 | "type": "zip", 2338 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/bc0f17bed914df2cceb989972c3b996043c4da4a", 2339 | "reference": "bc0f17bed914df2cceb989972c3b996043c4da4a", 2340 | "shasum": "" 2341 | }, 2342 | "require": { 2343 | "php": ">=5.5.9" 2344 | }, 2345 | "type": "library", 2346 | "extra": { 2347 | "branch-alias": { 2348 | "dev-master": "3.2-dev" 2349 | } 2350 | }, 2351 | "autoload": { 2352 | "psr-4": { 2353 | "Symfony\\Component\\Filesystem\\": "" 2354 | }, 2355 | "exclude-from-classmap": [ 2356 | "/Tests/" 2357 | ] 2358 | }, 2359 | "notification-url": "https://packagist.org/downloads/", 2360 | "license": [ 2361 | "MIT" 2362 | ], 2363 | "authors": [ 2364 | { 2365 | "name": "Fabien Potencier", 2366 | "email": "fabien@symfony.com" 2367 | }, 2368 | { 2369 | "name": "Symfony Community", 2370 | "homepage": "https://symfony.com/contributors" 2371 | } 2372 | ], 2373 | "description": "Symfony Filesystem Component", 2374 | "homepage": "https://symfony.com", 2375 | "time": "2017-03-06T19:30:27+00:00" 2376 | }, 2377 | { 2378 | "name": "symfony/translation", 2379 | "version": "v3.2.6", 2380 | "source": { 2381 | "type": "git", 2382 | "url": "https://github.com/symfony/translation.git", 2383 | "reference": "0e1b15ce8fbf3890f4ccdac430ed5e07fdfe0690" 2384 | }, 2385 | "dist": { 2386 | "type": "zip", 2387 | "url": "https://api.github.com/repos/symfony/translation/zipball/0e1b15ce8fbf3890f4ccdac430ed5e07fdfe0690", 2388 | "reference": "0e1b15ce8fbf3890f4ccdac430ed5e07fdfe0690", 2389 | "shasum": "" 2390 | }, 2391 | "require": { 2392 | "php": ">=5.5.9", 2393 | "symfony/polyfill-mbstring": "~1.0" 2394 | }, 2395 | "conflict": { 2396 | "symfony/config": "<2.8" 2397 | }, 2398 | "require-dev": { 2399 | "psr/log": "~1.0", 2400 | "symfony/config": "~2.8|~3.0", 2401 | "symfony/intl": "^2.8.18|^3.2.5", 2402 | "symfony/yaml": "~2.8|~3.0" 2403 | }, 2404 | "suggest": { 2405 | "psr/log": "To use logging capability in translator", 2406 | "symfony/config": "", 2407 | "symfony/yaml": "" 2408 | }, 2409 | "type": "library", 2410 | "extra": { 2411 | "branch-alias": { 2412 | "dev-master": "3.2-dev" 2413 | } 2414 | }, 2415 | "autoload": { 2416 | "psr-4": { 2417 | "Symfony\\Component\\Translation\\": "" 2418 | }, 2419 | "exclude-from-classmap": [ 2420 | "/Tests/" 2421 | ] 2422 | }, 2423 | "notification-url": "https://packagist.org/downloads/", 2424 | "license": [ 2425 | "MIT" 2426 | ], 2427 | "authors": [ 2428 | { 2429 | "name": "Fabien Potencier", 2430 | "email": "fabien@symfony.com" 2431 | }, 2432 | { 2433 | "name": "Symfony Community", 2434 | "homepage": "https://symfony.com/contributors" 2435 | } 2436 | ], 2437 | "description": "Symfony Translation Component", 2438 | "homepage": "https://symfony.com", 2439 | "time": "2017-03-04T12:23:14+00:00" 2440 | }, 2441 | { 2442 | "name": "symfony/yaml", 2443 | "version": "v3.2.6", 2444 | "source": { 2445 | "type": "git", 2446 | "url": "https://github.com/symfony/yaml.git", 2447 | "reference": "093e416ad096355149e265ea2e4cc1f9ee40ab1a" 2448 | }, 2449 | "dist": { 2450 | "type": "zip", 2451 | "url": "https://api.github.com/repos/symfony/yaml/zipball/093e416ad096355149e265ea2e4cc1f9ee40ab1a", 2452 | "reference": "093e416ad096355149e265ea2e4cc1f9ee40ab1a", 2453 | "shasum": "" 2454 | }, 2455 | "require": { 2456 | "php": ">=5.5.9" 2457 | }, 2458 | "require-dev": { 2459 | "symfony/console": "~2.8|~3.0" 2460 | }, 2461 | "suggest": { 2462 | "symfony/console": "For validating YAML files using the lint command" 2463 | }, 2464 | "type": "library", 2465 | "extra": { 2466 | "branch-alias": { 2467 | "dev-master": "3.2-dev" 2468 | } 2469 | }, 2470 | "autoload": { 2471 | "psr-4": { 2472 | "Symfony\\Component\\Yaml\\": "" 2473 | }, 2474 | "exclude-from-classmap": [ 2475 | "/Tests/" 2476 | ] 2477 | }, 2478 | "notification-url": "https://packagist.org/downloads/", 2479 | "license": [ 2480 | "MIT" 2481 | ], 2482 | "authors": [ 2483 | { 2484 | "name": "Fabien Potencier", 2485 | "email": "fabien@symfony.com" 2486 | }, 2487 | { 2488 | "name": "Symfony Community", 2489 | "homepage": "https://symfony.com/contributors" 2490 | } 2491 | ], 2492 | "description": "Symfony Yaml Component", 2493 | "homepage": "https://symfony.com", 2494 | "time": "2017-03-07T16:47:02+00:00" 2495 | } 2496 | ], 2497 | "aliases": [], 2498 | "minimum-stability": "stable", 2499 | "stability-flags": [], 2500 | "prefer-stable": false, 2501 | "prefer-lowest": false, 2502 | "platform": [], 2503 | "platform-dev": { 2504 | "php": "^7.0" 2505 | } 2506 | } 2507 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | devtools: 5 | build: docker/devtools/ 6 | image: matthiasnoback/tactical-ddd-workshop-devtools 7 | volumes: 8 | - ./:/opt 9 | - ${COMPOSER_HOME}:/home/.composer 10 | environment: 11 | COMPOSER_HOME: /home/.composer 12 | XDEBUG_CONFIG: "remote_host=${DOCKER_HOST_IP}" 13 | PHP_IDE_CONFIG: "serverName=docker" 14 | user: ${HOST_UID}:${HOST_GID} 15 | -------------------------------------------------------------------------------- /docker/devtools/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM matthiasnoback/php_workshop_tools_base:latest 2 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | ./test 9 | 10 | 11 | 12 | 13 | src/ 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /sandbox.php: -------------------------------------------------------------------------------- 1 | subscribeToAllEvents(new EventCliLogger()); 18 | 19 | $user = new User( 20 | $userRepository->nextIdentity(), 21 | 'Matthias Noback', 22 | 'matthiasnoback@gmail.com' 23 | ); 24 | $userRepository->add($user); 25 | 26 | $meetupGroup = new MeetupGroup( 27 | $meetupGroupRepository->nextIdentity(), 28 | 'Ibuildings Events' 29 | ); 30 | $meetupGroupRepository->add($meetupGroup); 31 | 32 | // dispatch domain events 33 | //$eventDispatcher->dispatch(new \stdClass()); 34 | -------------------------------------------------------------------------------- /src/MeetupOrganizing/Domain/Model/MeetupGroup/MeetupGroup.php: -------------------------------------------------------------------------------- 1 | meetupGroupId = $meetupGroupId; 28 | $this->name = $name; 29 | } 30 | 31 | /** 32 | * @return MeetupGroupId 33 | */ 34 | public function meetupGroupId(): MeetupGroupId 35 | { 36 | return $this->meetupGroupId; 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function name(): string 43 | { 44 | return $this->name; 45 | } 46 | 47 | public function addMember(UserId $memberId) 48 | { 49 | $this->memberIds[] = $memberId; 50 | } 51 | 52 | public function memberIds(): array 53 | { 54 | return $this->memberIds; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/MeetupOrganizing/Domain/Model/MeetupGroup/MeetupGroupId.php: -------------------------------------------------------------------------------- 1 | userId = $userId; 26 | $this->name = $name; 27 | $this->emailAddress = $emailAddress; 28 | } 29 | 30 | /** 31 | * @return UserId 32 | */ 33 | public function userId(): UserId 34 | { 35 | return $this->userId; 36 | } 37 | 38 | /** 39 | * @return string 40 | */ 41 | public function name(): string 42 | { 43 | return $this->name; 44 | } 45 | 46 | /** 47 | * @return string 48 | */ 49 | public function emailAddress() 50 | { 51 | return $this->emailAddress; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/MeetupOrganizing/Domain/Model/User/UserId.php: -------------------------------------------------------------------------------- 1 | meetupGroups[(string)$meetupGroup->meetupGroupId()] = $meetupGroup; 18 | } 19 | 20 | public function getById(MeetupGroupId $meetupGroupId): MeetupGroup 21 | { 22 | if (!isset($this->meetupGroups[(string)$meetupGroupId])) { 23 | throw new \RuntimeException(sprintf('Meetup group "%s" not found', $meetupGroupId)); 24 | } 25 | 26 | return $this->meetupGroups[(string)$meetupGroupId]; 27 | } 28 | 29 | public function nextIdentity(): MeetupGroupId 30 | { 31 | return MeetupGroupId::fromString((string)Uuid::uuid4()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/MeetupOrganizing/Infrastructure/Persistence/InMemoryUserRepository.php: -------------------------------------------------------------------------------- 1 | users[(string)$user->userId()] = $user; 18 | } 19 | 20 | public function getById(UserId $userId): User 21 | { 22 | if (!isset($this->users[(string)$userId])) { 23 | throw new \RuntimeException(sprintf('User "%s" not found', $userId)); 24 | } 25 | 26 | return $this->users[(string)$userId]; 27 | } 28 | 29 | public function nextIdentity(): UserId 30 | { 31 | return UserId::fromString((string)Uuid::uuid4()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/Test/Unit/MeetupOrganizing/Domain/Model/MeetupGroupTest.php: -------------------------------------------------------------------------------- 1 | assertSame($name, $meetupGroup->name()); 22 | $this->assertEquals($meetupGroupId, $meetupGroup->meetupGroupId()); 23 | } 24 | 25 | /** 26 | * @test 27 | */ 28 | public function it_accepts_new_members() 29 | { 30 | $memberId1 = UserId::fromString((string)Uuid::uuid4()); 31 | $memberId2 = UserId::fromString((string)Uuid::uuid4()); 32 | 33 | $meetupGroup = new MeetupGroup( 34 | MeetupGroupId::fromString((string)Uuid::uuid4()), 35 | 'Ibuildings Events' 36 | ); 37 | $meetupGroup->addMember($memberId1); 38 | $meetupGroup->addMember($memberId2); 39 | 40 | $this->assertSame([$memberId1, $memberId2], $meetupGroup->memberIds()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/Test/Unit/MeetupOrganizing/Domain/Model/UserTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($userId, $user->userId()); 22 | $this->assertEquals($name, $user->name()); 23 | $this->assertEquals($emailAddress, $user->emailAddress()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/Test/Unit/MeetupOrganizing/Infrastructure/Persistence/InMemoryMeetupGroupRepositoryTest.php: -------------------------------------------------------------------------------- 1 | add($meetupGroup); 23 | 24 | $retrievedUser = $repository->getById($meetupGroupId); 25 | $this->assertSame($meetupGroup, $retrievedUser); 26 | } 27 | 28 | /** 29 | * @test 30 | */ 31 | public function it_fails_when_the_given_meetup_group_does_not_exist() 32 | { 33 | $repository = new InMemoryMeetupGroupRepository(); 34 | $this->expectException(\RuntimeException::class); 35 | 36 | $repository->getById(MeetupGroupId::fromString('ae9ab5d9-51c6-4a3a-b26a-5f30bacc3a77')); 37 | } 38 | 39 | /** 40 | * @test 41 | */ 42 | public function it_provides_a_next_identity() 43 | { 44 | $repository = new InMemoryMeetupGroupRepository(); 45 | 46 | $this->assertInstanceOf(MeetupGroupId::class, $repository->nextIdentity()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test/Test/Unit/MeetupOrganizing/Infrastructure/Persistence/InMemoryUserRepositoryTest.php: -------------------------------------------------------------------------------- 1 | add($user); 23 | 24 | $retrievedUser = $repository->getById($userId); 25 | $this->assertSame($user, $retrievedUser); 26 | } 27 | 28 | /** 29 | * @test 30 | */ 31 | public function it_fails_when_the_given_meetup_group_does_not_exist() 32 | { 33 | $repository = new InMemoryUserRepository(); 34 | $this->expectException(\RuntimeException::class); 35 | 36 | $repository->getById(UserId::fromString('ae9ab5d9-51c6-4a3a-b26a-5f30bacc3a77')); 37 | } 38 | 39 | /** 40 | * @test 41 | */ 42 | public function it_provides_a_next_identity() 43 | { 44 | $repository = new InMemoryUserRepository(); 45 | 46 | $this->assertInstanceOf(UserId::class, $repository->nextIdentity()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test/bootstrap.php: -------------------------------------------------------------------------------- 1 |