├── .gitignore
├── GOTCHAS.md
├── README.md
├── bootstrap.php
├── cli-config.php
├── command-bus.php
├── composer.json
├── composer.lock
├── data
├── .gitignore
└── proxies
│ └── .gitignore
├── mapping
├── Authentication.Entity.User.dcm.xml
├── Enforcement.Entity.EnforcementRequest.dcm.xml
└── Library.BookAmount.dcm.xml
├── migrations.xml
├── migrations
└── Version20160428103311.php
├── phpunit.xml.dist
├── public
├── add-book.php
├── enforcement-notices.php
├── fake-login.php
├── lend-book-to-user.php
├── list-books.php
├── remove-book.php
└── return-book.php
├── run.sh
├── src
├── Authentication
│ └── Entity
│ │ └── User.php
├── DoctrineIntegration
│ └── Library
│ │ ├── AmountType.php
│ │ ├── ISBNType.php
│ │ └── LibraryIdType.php
├── Enforcement
│ └── Entity
│ │ └── EnforcementRequest.php
└── Library
│ ├── Amount.php
│ ├── Book.php
│ ├── BookAmount.php
│ ├── Command
│ └── AddBook.php
│ ├── DoctrineLibraryRepository.php
│ ├── ISBN.php
│ ├── LentBook.php
│ ├── Library.php
│ ├── LibraryId.php
│ ├── LibraryRepository.php
│ └── UserId.php
└── test
├── DoctrineIntegration
└── BookAmountPersistenceTest.php
└── Library
├── AmountTest.php
├── DoctrineLibraryRepositoryTest.php
├── ISBNTest.php
├── LibraryIdTest.php
├── LibraryTest.php
└── UserIdTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor
2 |
--------------------------------------------------------------------------------
/GOTCHAS.md:
--------------------------------------------------------------------------------
1 | * Auto-return systems may track single books, instead of just amounts
2 | * ISBNs are not necessarily unique - ancient systems may have non-unique ISBNs
3 | * Is a 0 amount allowed?
4 | * ISBNs now allow other chars too
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Maintainable Doctrine ORM tutorial
2 |
3 | This tutorial will introduce you to using Doctrine ORM in a more maintainable way.
4 |
5 | Specifically, following concepts will be covered:
6 |
7 | 1. Aggregate root (Is it an Entity?)
8 | 2. Value Object
9 | 3. Commands
10 | 4. Command bus
11 | 5. Isolating domain and application logic
12 | 6. Maintaining transactional integrity whilst keeping domain boundaries separate
13 | 7. Transactional integrity and domain boundaries
14 | 8. Maintaining schema changes versioned
15 |
16 | ## The domain
17 |
18 | The domain used as reference is a Library (books) management system.
19 | We will not focus much on DDD-style exploration, but we will instead
20 | focus on writing the logic for an already existing specification:
21 |
22 | * User management system will be mocked out
23 | * Searching for books
24 | * Lending books to users
25 | * Managing maximum number of books that can be lent by a user at any given time
26 | * Getting books back from users
27 | * Notifying users that they should return a book
28 | * Fine users that didn't return a book after a notice (communication with external "enforcement" context)
29 |
30 | ## Installation
31 |
32 | First, [install composer](https://getcomposer.org/download/).
33 |
34 | After that, you can run:
35 |
36 | ```sh
37 | composer require doctrine/orm
38 | ```
39 |
40 | We now need to set up autoloading:
41 |
42 | ```json
43 | {
44 | "autoload": {
45 | "psr-4": {
46 | "Authentication": "src/Authentication",
47 | "Library": "src/Library",
48 | "Enforcement": "src/Enforcement",
49 | }
50 | }
51 | }
52 | ```
53 |
54 | ## Schedule
55 |
56 | * 10m - presentation round
57 | * 10m - pairing - discussion is at the core of the process
58 | * 10m - base concepts: aggregate root/value object
59 | * 5m - domain (and the 3 boundaries - auth, library, enforcement):
60 | * library
61 | * library contains books
62 | * each book has an ISBN and some metadata
63 | * can add books to the library
64 | * can register users
65 | * can lend books to users
66 | * users have a max lent books amount
67 | * users need to be notified when a lend is overdue
68 | * overdue lend must be enforced after a certain threshold (external API)
69 | * returned books should cancel enforcement requests (external API)
70 | * ask questions - what else can a library do? Is the specification sufficient?
71 | * 5m - domain bits to be implemented:
72 | * adding books
73 | * listing available books (assuming small to large bibliotheque)
74 | * lend a book (user)
75 | * return a book
76 | * notify user of late lent return
77 | * enforce return of very late lent
78 | * logging all operations (audit log or immutable structures)
79 | * avoid lazy-loading all the book catalogue
80 | * 30m - try designing a library or repository with just "add book" and "list all books" without memory issues
81 | * 15m - writing the library object together
82 | * custom repositories
83 | * passing repositories to entities?
84 | * 10m - hardening the logic with value-objects
85 | * 15m - wiring together everything via XML mappings
86 | * 10m - installing and configuring doctrine migrations, generating first migration files
87 | * 5m - transactional safety - it is needed now that we do live-queries at all times
88 | * 10m - transactional safety at the base of every interaction via a command bus
89 | * 45m - implementing book lends and returns (with commands, VOs and serialize/unserialize)
90 | * 15m - implementing lending books/returning books together
91 | * 20m - send notifications to users with overdue returns, don't dog-pile notifications
92 | * 10m - code notifications for overdue returns together
93 | * 20m - interaction with external system: coding together the notification system
94 | * 5m - logging some queries
95 | * 15m - setting up the second level cache, seeing it in action
96 |
--------------------------------------------------------------------------------
/bootstrap.php:
--------------------------------------------------------------------------------
1 | setMetadataDriverImpl(new XmlDriver([__DIR__ . '/mapping']));
20 |
21 | // This is needed for Doctrine to generate files required for lazy-loading
22 | $configuration->setProxyDir(__DIR__ . '/data/proxies');
23 | $configuration->setProxyNamespace('DoctrineProxies');
24 |
25 | // We are telling Doctrine to always generate files required for lazy-loading. This is a slow operation,
26 | // and shouldn't be done in a production environment.
27 | $configuration->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_ALWAYS);
28 |
29 | Type::addType(UuidType::class, UuidType::class);
30 | Type::addType(AmountType::class, AmountType::class);
31 | Type::addType(ISBNType::class, ISBNType::class);
32 | Type::addType(LibraryIdType::class, LibraryIdType::class);
33 |
34 | // Finally creating the EntityManager: our entry point for the ORM
35 | return EntityManager::create(
36 | [
37 | 'driverClass' => Driver::class,
38 | 'path' => __DIR__ . '/data/test-db.sqlite',
39 | ],
40 | $configuration
41 | );
42 |
--------------------------------------------------------------------------------
/cli-config.php:
--------------------------------------------------------------------------------
1 | getConnection());
11 |
12 | return new HelperSet([
13 | 'em' => new EntityManagerHelper($entityManager),
14 | 'db' => $connectionHelper,
15 | 'connection' => $connectionHelper,
16 | ]);
17 |
--------------------------------------------------------------------------------
/command-bus.php:
--------------------------------------------------------------------------------
1 | getLibraryId(),
19 | new DoctrineLibraryRepository(
20 | $entityManager->getRepository(BookAmount::class),
21 | $entityManager
22 | )
23 | );
24 |
25 | $library->addBook($command->getIsbn(), $command->getAmount());
26 | return;
27 | }
28 |
29 | throw new \InvalidArgumentException(sprintf('Unknown command %s', get_class($command)));
30 | };
31 |
32 | $logger = function ($command) {
33 | var_dump($command);
34 | };
35 |
36 | $commandBus = function ($command) use ($commandBus, $logger) {
37 | $logger($command);
38 |
39 | return $commandBus($command);
40 | };
41 |
42 | $commandBus = function ($command) use ($commandBus, $entityManager) {
43 | $return = $entityManager->transactional(function () use ($commandBus, $command) {
44 | return $commandBus($command);
45 | });
46 |
47 | $entityManager->clear();
48 |
49 | return $return;
50 | };
51 |
52 | return $commandBus;
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "doctrine/orm": "^2.5",
4 | "ramsey/uuid": "^3.4",
5 | "ramsey/uuid-doctrine": "^1.2",
6 | "doctrine/migrations": "^1.4",
7 | "phpunit/phpunit": "^4.8"
8 | },
9 | "autoload": {
10 | "psr-4": {
11 | "DoctrineIntegration\\": "src/DoctrineIntegration",
12 | "Authentication\\": "src/Authentication",
13 | "Library\\": "src/Library",
14 | "Enforcement\\": "src/Enforcement"
15 | }
16 | },
17 | "config": {
18 | "platform": {
19 | "php": "5.5.9"
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/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 | "hash": "ce7f7d6ae767e1efb232cb005225c523",
8 | "content-hash": "2884309267c035d2d63be54f225c79de",
9 | "packages": [
10 | {
11 | "name": "doctrine/annotations",
12 | "version": "v1.2.7",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/doctrine/annotations.git",
16 | "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
21 | "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "doctrine/lexer": "1.*",
26 | "php": ">=5.3.2"
27 | },
28 | "require-dev": {
29 | "doctrine/cache": "1.*",
30 | "phpunit/phpunit": "4.*"
31 | },
32 | "type": "library",
33 | "extra": {
34 | "branch-alias": {
35 | "dev-master": "1.3.x-dev"
36 | }
37 | },
38 | "autoload": {
39 | "psr-0": {
40 | "Doctrine\\Common\\Annotations\\": "lib/"
41 | }
42 | },
43 | "notification-url": "https://packagist.org/downloads/",
44 | "license": [
45 | "MIT"
46 | ],
47 | "authors": [
48 | {
49 | "name": "Roman Borschel",
50 | "email": "roman@code-factory.org"
51 | },
52 | {
53 | "name": "Benjamin Eberlei",
54 | "email": "kontakt@beberlei.de"
55 | },
56 | {
57 | "name": "Guilherme Blanco",
58 | "email": "guilhermeblanco@gmail.com"
59 | },
60 | {
61 | "name": "Jonathan Wage",
62 | "email": "jonwage@gmail.com"
63 | },
64 | {
65 | "name": "Johannes Schmitt",
66 | "email": "schmittjoh@gmail.com"
67 | }
68 | ],
69 | "description": "Docblock Annotations Parser",
70 | "homepage": "http://www.doctrine-project.org",
71 | "keywords": [
72 | "annotations",
73 | "docblock",
74 | "parser"
75 | ],
76 | "time": "2015-08-31 12:32:49"
77 | },
78 | {
79 | "name": "doctrine/cache",
80 | "version": "v1.6.0",
81 | "source": {
82 | "type": "git",
83 | "url": "https://github.com/doctrine/cache.git",
84 | "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6"
85 | },
86 | "dist": {
87 | "type": "zip",
88 | "url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6",
89 | "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6",
90 | "shasum": ""
91 | },
92 | "require": {
93 | "php": "~5.5|~7.0"
94 | },
95 | "conflict": {
96 | "doctrine/common": ">2.2,<2.4"
97 | },
98 | "require-dev": {
99 | "phpunit/phpunit": "~4.8|~5.0",
100 | "predis/predis": "~1.0",
101 | "satooshi/php-coveralls": "~0.6"
102 | },
103 | "type": "library",
104 | "extra": {
105 | "branch-alias": {
106 | "dev-master": "1.6.x-dev"
107 | }
108 | },
109 | "autoload": {
110 | "psr-4": {
111 | "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
112 | }
113 | },
114 | "notification-url": "https://packagist.org/downloads/",
115 | "license": [
116 | "MIT"
117 | ],
118 | "authors": [
119 | {
120 | "name": "Roman Borschel",
121 | "email": "roman@code-factory.org"
122 | },
123 | {
124 | "name": "Benjamin Eberlei",
125 | "email": "kontakt@beberlei.de"
126 | },
127 | {
128 | "name": "Guilherme Blanco",
129 | "email": "guilhermeblanco@gmail.com"
130 | },
131 | {
132 | "name": "Jonathan Wage",
133 | "email": "jonwage@gmail.com"
134 | },
135 | {
136 | "name": "Johannes Schmitt",
137 | "email": "schmittjoh@gmail.com"
138 | }
139 | ],
140 | "description": "Caching library offering an object-oriented API for many cache backends",
141 | "homepage": "http://www.doctrine-project.org",
142 | "keywords": [
143 | "cache",
144 | "caching"
145 | ],
146 | "time": "2015-12-31 16:37:02"
147 | },
148 | {
149 | "name": "doctrine/collections",
150 | "version": "v1.3.0",
151 | "source": {
152 | "type": "git",
153 | "url": "https://github.com/doctrine/collections.git",
154 | "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
155 | },
156 | "dist": {
157 | "type": "zip",
158 | "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
159 | "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
160 | "shasum": ""
161 | },
162 | "require": {
163 | "php": ">=5.3.2"
164 | },
165 | "require-dev": {
166 | "phpunit/phpunit": "~4.0"
167 | },
168 | "type": "library",
169 | "extra": {
170 | "branch-alias": {
171 | "dev-master": "1.2.x-dev"
172 | }
173 | },
174 | "autoload": {
175 | "psr-0": {
176 | "Doctrine\\Common\\Collections\\": "lib/"
177 | }
178 | },
179 | "notification-url": "https://packagist.org/downloads/",
180 | "license": [
181 | "MIT"
182 | ],
183 | "authors": [
184 | {
185 | "name": "Roman Borschel",
186 | "email": "roman@code-factory.org"
187 | },
188 | {
189 | "name": "Benjamin Eberlei",
190 | "email": "kontakt@beberlei.de"
191 | },
192 | {
193 | "name": "Guilherme Blanco",
194 | "email": "guilhermeblanco@gmail.com"
195 | },
196 | {
197 | "name": "Jonathan Wage",
198 | "email": "jonwage@gmail.com"
199 | },
200 | {
201 | "name": "Johannes Schmitt",
202 | "email": "schmittjoh@gmail.com"
203 | }
204 | ],
205 | "description": "Collections Abstraction library",
206 | "homepage": "http://www.doctrine-project.org",
207 | "keywords": [
208 | "array",
209 | "collections",
210 | "iterator"
211 | ],
212 | "time": "2015-04-14 22:21:58"
213 | },
214 | {
215 | "name": "doctrine/common",
216 | "version": "v2.6.1",
217 | "source": {
218 | "type": "git",
219 | "url": "https://github.com/doctrine/common.git",
220 | "reference": "a579557bc689580c19fee4e27487a67fe60defc0"
221 | },
222 | "dist": {
223 | "type": "zip",
224 | "url": "https://api.github.com/repos/doctrine/common/zipball/a579557bc689580c19fee4e27487a67fe60defc0",
225 | "reference": "a579557bc689580c19fee4e27487a67fe60defc0",
226 | "shasum": ""
227 | },
228 | "require": {
229 | "doctrine/annotations": "1.*",
230 | "doctrine/cache": "1.*",
231 | "doctrine/collections": "1.*",
232 | "doctrine/inflector": "1.*",
233 | "doctrine/lexer": "1.*",
234 | "php": "~5.5|~7.0"
235 | },
236 | "require-dev": {
237 | "phpunit/phpunit": "~4.8|~5.0"
238 | },
239 | "type": "library",
240 | "extra": {
241 | "branch-alias": {
242 | "dev-master": "2.7.x-dev"
243 | }
244 | },
245 | "autoload": {
246 | "psr-4": {
247 | "Doctrine\\Common\\": "lib/Doctrine/Common"
248 | }
249 | },
250 | "notification-url": "https://packagist.org/downloads/",
251 | "license": [
252 | "MIT"
253 | ],
254 | "authors": [
255 | {
256 | "name": "Roman Borschel",
257 | "email": "roman@code-factory.org"
258 | },
259 | {
260 | "name": "Benjamin Eberlei",
261 | "email": "kontakt@beberlei.de"
262 | },
263 | {
264 | "name": "Guilherme Blanco",
265 | "email": "guilhermeblanco@gmail.com"
266 | },
267 | {
268 | "name": "Jonathan Wage",
269 | "email": "jonwage@gmail.com"
270 | },
271 | {
272 | "name": "Johannes Schmitt",
273 | "email": "schmittjoh@gmail.com"
274 | }
275 | ],
276 | "description": "Common Library for Doctrine projects",
277 | "homepage": "http://www.doctrine-project.org",
278 | "keywords": [
279 | "annotations",
280 | "collections",
281 | "eventmanager",
282 | "persistence",
283 | "spl"
284 | ],
285 | "time": "2015-12-25 13:18:31"
286 | },
287 | {
288 | "name": "doctrine/dbal",
289 | "version": "v2.5.4",
290 | "source": {
291 | "type": "git",
292 | "url": "https://github.com/doctrine/dbal.git",
293 | "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769"
294 | },
295 | "dist": {
296 | "type": "zip",
297 | "url": "https://api.github.com/repos/doctrine/dbal/zipball/abbdfd1cff43a7b99d027af3be709bc8fc7d4769",
298 | "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769",
299 | "shasum": ""
300 | },
301 | "require": {
302 | "doctrine/common": ">=2.4,<2.7-dev",
303 | "php": ">=5.3.2"
304 | },
305 | "require-dev": {
306 | "phpunit/phpunit": "4.*",
307 | "symfony/console": "2.*"
308 | },
309 | "suggest": {
310 | "symfony/console": "For helpful console commands such as SQL execution and import of files."
311 | },
312 | "bin": [
313 | "bin/doctrine-dbal"
314 | ],
315 | "type": "library",
316 | "extra": {
317 | "branch-alias": {
318 | "dev-master": "2.5.x-dev"
319 | }
320 | },
321 | "autoload": {
322 | "psr-0": {
323 | "Doctrine\\DBAL\\": "lib/"
324 | }
325 | },
326 | "notification-url": "https://packagist.org/downloads/",
327 | "license": [
328 | "MIT"
329 | ],
330 | "authors": [
331 | {
332 | "name": "Roman Borschel",
333 | "email": "roman@code-factory.org"
334 | },
335 | {
336 | "name": "Benjamin Eberlei",
337 | "email": "kontakt@beberlei.de"
338 | },
339 | {
340 | "name": "Guilherme Blanco",
341 | "email": "guilhermeblanco@gmail.com"
342 | },
343 | {
344 | "name": "Jonathan Wage",
345 | "email": "jonwage@gmail.com"
346 | }
347 | ],
348 | "description": "Database Abstraction Layer",
349 | "homepage": "http://www.doctrine-project.org",
350 | "keywords": [
351 | "database",
352 | "dbal",
353 | "persistence",
354 | "queryobject"
355 | ],
356 | "time": "2016-01-05 22:11:12"
357 | },
358 | {
359 | "name": "doctrine/inflector",
360 | "version": "v1.1.0",
361 | "source": {
362 | "type": "git",
363 | "url": "https://github.com/doctrine/inflector.git",
364 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae"
365 | },
366 | "dist": {
367 | "type": "zip",
368 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae",
369 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae",
370 | "shasum": ""
371 | },
372 | "require": {
373 | "php": ">=5.3.2"
374 | },
375 | "require-dev": {
376 | "phpunit/phpunit": "4.*"
377 | },
378 | "type": "library",
379 | "extra": {
380 | "branch-alias": {
381 | "dev-master": "1.1.x-dev"
382 | }
383 | },
384 | "autoload": {
385 | "psr-0": {
386 | "Doctrine\\Common\\Inflector\\": "lib/"
387 | }
388 | },
389 | "notification-url": "https://packagist.org/downloads/",
390 | "license": [
391 | "MIT"
392 | ],
393 | "authors": [
394 | {
395 | "name": "Roman Borschel",
396 | "email": "roman@code-factory.org"
397 | },
398 | {
399 | "name": "Benjamin Eberlei",
400 | "email": "kontakt@beberlei.de"
401 | },
402 | {
403 | "name": "Guilherme Blanco",
404 | "email": "guilhermeblanco@gmail.com"
405 | },
406 | {
407 | "name": "Jonathan Wage",
408 | "email": "jonwage@gmail.com"
409 | },
410 | {
411 | "name": "Johannes Schmitt",
412 | "email": "schmittjoh@gmail.com"
413 | }
414 | ],
415 | "description": "Common String Manipulations with regard to casing and singular/plural rules.",
416 | "homepage": "http://www.doctrine-project.org",
417 | "keywords": [
418 | "inflection",
419 | "pluralize",
420 | "singularize",
421 | "string"
422 | ],
423 | "time": "2015-11-06 14:35:42"
424 | },
425 | {
426 | "name": "doctrine/instantiator",
427 | "version": "1.0.5",
428 | "source": {
429 | "type": "git",
430 | "url": "https://github.com/doctrine/instantiator.git",
431 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
432 | },
433 | "dist": {
434 | "type": "zip",
435 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
436 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
437 | "shasum": ""
438 | },
439 | "require": {
440 | "php": ">=5.3,<8.0-DEV"
441 | },
442 | "require-dev": {
443 | "athletic/athletic": "~0.1.8",
444 | "ext-pdo": "*",
445 | "ext-phar": "*",
446 | "phpunit/phpunit": "~4.0",
447 | "squizlabs/php_codesniffer": "~2.0"
448 | },
449 | "type": "library",
450 | "extra": {
451 | "branch-alias": {
452 | "dev-master": "1.0.x-dev"
453 | }
454 | },
455 | "autoload": {
456 | "psr-4": {
457 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
458 | }
459 | },
460 | "notification-url": "https://packagist.org/downloads/",
461 | "license": [
462 | "MIT"
463 | ],
464 | "authors": [
465 | {
466 | "name": "Marco Pivetta",
467 | "email": "ocramius@gmail.com",
468 | "homepage": "http://ocramius.github.com/"
469 | }
470 | ],
471 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
472 | "homepage": "https://github.com/doctrine/instantiator",
473 | "keywords": [
474 | "constructor",
475 | "instantiate"
476 | ],
477 | "time": "2015-06-14 21:17:01"
478 | },
479 | {
480 | "name": "doctrine/lexer",
481 | "version": "v1.0.1",
482 | "source": {
483 | "type": "git",
484 | "url": "https://github.com/doctrine/lexer.git",
485 | "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
486 | },
487 | "dist": {
488 | "type": "zip",
489 | "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
490 | "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
491 | "shasum": ""
492 | },
493 | "require": {
494 | "php": ">=5.3.2"
495 | },
496 | "type": "library",
497 | "extra": {
498 | "branch-alias": {
499 | "dev-master": "1.0.x-dev"
500 | }
501 | },
502 | "autoload": {
503 | "psr-0": {
504 | "Doctrine\\Common\\Lexer\\": "lib/"
505 | }
506 | },
507 | "notification-url": "https://packagist.org/downloads/",
508 | "license": [
509 | "MIT"
510 | ],
511 | "authors": [
512 | {
513 | "name": "Roman Borschel",
514 | "email": "roman@code-factory.org"
515 | },
516 | {
517 | "name": "Guilherme Blanco",
518 | "email": "guilhermeblanco@gmail.com"
519 | },
520 | {
521 | "name": "Johannes Schmitt",
522 | "email": "schmittjoh@gmail.com"
523 | }
524 | ],
525 | "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
526 | "homepage": "http://www.doctrine-project.org",
527 | "keywords": [
528 | "lexer",
529 | "parser"
530 | ],
531 | "time": "2014-09-09 13:34:57"
532 | },
533 | {
534 | "name": "doctrine/migrations",
535 | "version": "1.4.1",
536 | "source": {
537 | "type": "git",
538 | "url": "https://github.com/doctrine/migrations.git",
539 | "reference": "0d0ff5da10c5d30846da32060bd9e357abf70a05"
540 | },
541 | "dist": {
542 | "type": "zip",
543 | "url": "https://api.github.com/repos/doctrine/migrations/zipball/0d0ff5da10c5d30846da32060bd9e357abf70a05",
544 | "reference": "0d0ff5da10c5d30846da32060bd9e357abf70a05",
545 | "shasum": ""
546 | },
547 | "require": {
548 | "doctrine/dbal": "~2.2",
549 | "ocramius/proxy-manager": "^1.0|^2.0",
550 | "php": "^5.5|^7.0",
551 | "symfony/console": "~2.3|~3.0",
552 | "symfony/yaml": "~2.3|~3.0"
553 | },
554 | "require-dev": {
555 | "doctrine/coding-standard": "dev-master",
556 | "doctrine/orm": "2.*",
557 | "jdorn/sql-formatter": "~1.1",
558 | "johnkary/phpunit-speedtrap": "~1.0@dev",
559 | "mockery/mockery": "^0.9.4",
560 | "phpunit/phpunit": "~4.7",
561 | "satooshi/php-coveralls": "0.6.*"
562 | },
563 | "suggest": {
564 | "jdorn/sql-formatter": "Allows to generate formatted SQL with the diff command."
565 | },
566 | "bin": [
567 | "bin/doctrine-migrations"
568 | ],
569 | "type": "library",
570 | "extra": {
571 | "branch-alias": {
572 | "dev-master": "v1.5.x-dev"
573 | }
574 | },
575 | "autoload": {
576 | "psr-4": {
577 | "Doctrine\\DBAL\\Migrations\\": "lib/Doctrine/DBAL/Migrations"
578 | }
579 | },
580 | "notification-url": "https://packagist.org/downloads/",
581 | "license": [
582 | "LGPL-2.1"
583 | ],
584 | "authors": [
585 | {
586 | "name": "Benjamin Eberlei",
587 | "email": "kontakt@beberlei.de"
588 | },
589 | {
590 | "name": "Jonathan Wage",
591 | "email": "jonwage@gmail.com"
592 | },
593 | {
594 | "name": "Michael Simonson",
595 | "email": "contact@mikesimonson.com"
596 | }
597 | ],
598 | "description": "Database Schema migrations using Doctrine DBAL",
599 | "homepage": "http://www.doctrine-project.org",
600 | "keywords": [
601 | "database",
602 | "migrations"
603 | ],
604 | "time": "2016-03-14 12:29:11"
605 | },
606 | {
607 | "name": "doctrine/orm",
608 | "version": "v2.5.4",
609 | "source": {
610 | "type": "git",
611 | "url": "https://github.com/doctrine/doctrine2.git",
612 | "reference": "bc4ddbfb0114cb33438cc811c9a740d8aa304aab"
613 | },
614 | "dist": {
615 | "type": "zip",
616 | "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/bc4ddbfb0114cb33438cc811c9a740d8aa304aab",
617 | "reference": "bc4ddbfb0114cb33438cc811c9a740d8aa304aab",
618 | "shasum": ""
619 | },
620 | "require": {
621 | "doctrine/cache": "~1.4",
622 | "doctrine/collections": "~1.2",
623 | "doctrine/common": ">=2.5-dev,<2.7-dev",
624 | "doctrine/dbal": ">=2.5-dev,<2.6-dev",
625 | "doctrine/instantiator": "~1.0.1",
626 | "ext-pdo": "*",
627 | "php": ">=5.4",
628 | "symfony/console": "~2.5|~3.0"
629 | },
630 | "require-dev": {
631 | "phpunit/phpunit": "~4.0",
632 | "symfony/yaml": "~2.3|~3.0"
633 | },
634 | "suggest": {
635 | "symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
636 | },
637 | "bin": [
638 | "bin/doctrine",
639 | "bin/doctrine.php"
640 | ],
641 | "type": "library",
642 | "extra": {
643 | "branch-alias": {
644 | "dev-master": "2.6.x-dev"
645 | }
646 | },
647 | "autoload": {
648 | "psr-0": {
649 | "Doctrine\\ORM\\": "lib/"
650 | }
651 | },
652 | "notification-url": "https://packagist.org/downloads/",
653 | "license": [
654 | "MIT"
655 | ],
656 | "authors": [
657 | {
658 | "name": "Roman Borschel",
659 | "email": "roman@code-factory.org"
660 | },
661 | {
662 | "name": "Benjamin Eberlei",
663 | "email": "kontakt@beberlei.de"
664 | },
665 | {
666 | "name": "Guilherme Blanco",
667 | "email": "guilhermeblanco@gmail.com"
668 | },
669 | {
670 | "name": "Jonathan Wage",
671 | "email": "jonwage@gmail.com"
672 | }
673 | ],
674 | "description": "Object-Relational-Mapper for PHP",
675 | "homepage": "http://www.doctrine-project.org",
676 | "keywords": [
677 | "database",
678 | "orm"
679 | ],
680 | "time": "2016-01-05 21:34:58"
681 | },
682 | {
683 | "name": "ocramius/proxy-manager",
684 | "version": "1.0.2",
685 | "source": {
686 | "type": "git",
687 | "url": "https://github.com/Ocramius/ProxyManager.git",
688 | "reference": "57e9272ec0e8deccf09421596e0e2252df440e11"
689 | },
690 | "dist": {
691 | "type": "zip",
692 | "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/57e9272ec0e8deccf09421596e0e2252df440e11",
693 | "reference": "57e9272ec0e8deccf09421596e0e2252df440e11",
694 | "shasum": ""
695 | },
696 | "require": {
697 | "php": ">=5.3.3",
698 | "zendframework/zend-code": ">2.2.5,<3.0"
699 | },
700 | "require-dev": {
701 | "ext-phar": "*",
702 | "phpunit/phpunit": "~4.0",
703 | "squizlabs/php_codesniffer": "1.5.*"
704 | },
705 | "suggest": {
706 | "ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects",
707 | "zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)",
708 | "zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)",
709 | "zendframework/zend-stdlib": "To use the hydrator proxy",
710 | "zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)"
711 | },
712 | "type": "library",
713 | "extra": {
714 | "branch-alias": {
715 | "dev-master": "2.0.x-dev"
716 | }
717 | },
718 | "autoload": {
719 | "psr-0": {
720 | "ProxyManager\\": "src"
721 | }
722 | },
723 | "notification-url": "https://packagist.org/downloads/",
724 | "license": [
725 | "MIT"
726 | ],
727 | "authors": [
728 | {
729 | "name": "Marco Pivetta",
730 | "email": "ocramius@gmail.com",
731 | "homepage": "http://ocramius.github.com/"
732 | }
733 | ],
734 | "description": "A library providing utilities to generate, instantiate and generally operate with Object Proxies",
735 | "homepage": "https://github.com/Ocramius/ProxyManager",
736 | "keywords": [
737 | "aop",
738 | "lazy loading",
739 | "proxy",
740 | "proxy pattern",
741 | "service proxies"
742 | ],
743 | "time": "2015-08-09 04:28:19"
744 | },
745 | {
746 | "name": "paragonie/random_compat",
747 | "version": "v2.0.2",
748 | "source": {
749 | "type": "git",
750 | "url": "https://github.com/paragonie/random_compat.git",
751 | "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf"
752 | },
753 | "dist": {
754 | "type": "zip",
755 | "url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf",
756 | "reference": "088c04e2f261c33bed6ca5245491cfca69195ccf",
757 | "shasum": ""
758 | },
759 | "require": {
760 | "php": ">=5.2.0"
761 | },
762 | "require-dev": {
763 | "phpunit/phpunit": "4.*|5.*"
764 | },
765 | "suggest": {
766 | "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
767 | },
768 | "type": "library",
769 | "autoload": {
770 | "files": [
771 | "lib/random.php"
772 | ]
773 | },
774 | "notification-url": "https://packagist.org/downloads/",
775 | "license": [
776 | "MIT"
777 | ],
778 | "authors": [
779 | {
780 | "name": "Paragon Initiative Enterprises",
781 | "email": "security@paragonie.com",
782 | "homepage": "https://paragonie.com"
783 | }
784 | ],
785 | "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
786 | "keywords": [
787 | "csprng",
788 | "pseudorandom",
789 | "random"
790 | ],
791 | "time": "2016-04-03 06:00:07"
792 | },
793 | {
794 | "name": "phpdocumentor/reflection-docblock",
795 | "version": "2.0.4",
796 | "source": {
797 | "type": "git",
798 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
799 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
800 | },
801 | "dist": {
802 | "type": "zip",
803 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
804 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
805 | "shasum": ""
806 | },
807 | "require": {
808 | "php": ">=5.3.3"
809 | },
810 | "require-dev": {
811 | "phpunit/phpunit": "~4.0"
812 | },
813 | "suggest": {
814 | "dflydev/markdown": "~1.0",
815 | "erusev/parsedown": "~1.0"
816 | },
817 | "type": "library",
818 | "extra": {
819 | "branch-alias": {
820 | "dev-master": "2.0.x-dev"
821 | }
822 | },
823 | "autoload": {
824 | "psr-0": {
825 | "phpDocumentor": [
826 | "src/"
827 | ]
828 | }
829 | },
830 | "notification-url": "https://packagist.org/downloads/",
831 | "license": [
832 | "MIT"
833 | ],
834 | "authors": [
835 | {
836 | "name": "Mike van Riel",
837 | "email": "mike.vanriel@naenius.com"
838 | }
839 | ],
840 | "time": "2015-02-03 12:10:50"
841 | },
842 | {
843 | "name": "phpspec/prophecy",
844 | "version": "v1.6.0",
845 | "source": {
846 | "type": "git",
847 | "url": "https://github.com/phpspec/prophecy.git",
848 | "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972"
849 | },
850 | "dist": {
851 | "type": "zip",
852 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972",
853 | "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972",
854 | "shasum": ""
855 | },
856 | "require": {
857 | "doctrine/instantiator": "^1.0.2",
858 | "php": "^5.3|^7.0",
859 | "phpdocumentor/reflection-docblock": "~2.0",
860 | "sebastian/comparator": "~1.1",
861 | "sebastian/recursion-context": "~1.0"
862 | },
863 | "require-dev": {
864 | "phpspec/phpspec": "~2.0"
865 | },
866 | "type": "library",
867 | "extra": {
868 | "branch-alias": {
869 | "dev-master": "1.5.x-dev"
870 | }
871 | },
872 | "autoload": {
873 | "psr-0": {
874 | "Prophecy\\": "src/"
875 | }
876 | },
877 | "notification-url": "https://packagist.org/downloads/",
878 | "license": [
879 | "MIT"
880 | ],
881 | "authors": [
882 | {
883 | "name": "Konstantin Kudryashov",
884 | "email": "ever.zet@gmail.com",
885 | "homepage": "http://everzet.com"
886 | },
887 | {
888 | "name": "Marcello Duarte",
889 | "email": "marcello.duarte@gmail.com"
890 | }
891 | ],
892 | "description": "Highly opinionated mocking framework for PHP 5.3+",
893 | "homepage": "https://github.com/phpspec/prophecy",
894 | "keywords": [
895 | "Double",
896 | "Dummy",
897 | "fake",
898 | "mock",
899 | "spy",
900 | "stub"
901 | ],
902 | "time": "2016-02-15 07:46:21"
903 | },
904 | {
905 | "name": "phpunit/php-code-coverage",
906 | "version": "2.2.4",
907 | "source": {
908 | "type": "git",
909 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
910 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
911 | },
912 | "dist": {
913 | "type": "zip",
914 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
915 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
916 | "shasum": ""
917 | },
918 | "require": {
919 | "php": ">=5.3.3",
920 | "phpunit/php-file-iterator": "~1.3",
921 | "phpunit/php-text-template": "~1.2",
922 | "phpunit/php-token-stream": "~1.3",
923 | "sebastian/environment": "^1.3.2",
924 | "sebastian/version": "~1.0"
925 | },
926 | "require-dev": {
927 | "ext-xdebug": ">=2.1.4",
928 | "phpunit/phpunit": "~4"
929 | },
930 | "suggest": {
931 | "ext-dom": "*",
932 | "ext-xdebug": ">=2.2.1",
933 | "ext-xmlwriter": "*"
934 | },
935 | "type": "library",
936 | "extra": {
937 | "branch-alias": {
938 | "dev-master": "2.2.x-dev"
939 | }
940 | },
941 | "autoload": {
942 | "classmap": [
943 | "src/"
944 | ]
945 | },
946 | "notification-url": "https://packagist.org/downloads/",
947 | "license": [
948 | "BSD-3-Clause"
949 | ],
950 | "authors": [
951 | {
952 | "name": "Sebastian Bergmann",
953 | "email": "sb@sebastian-bergmann.de",
954 | "role": "lead"
955 | }
956 | ],
957 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
958 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
959 | "keywords": [
960 | "coverage",
961 | "testing",
962 | "xunit"
963 | ],
964 | "time": "2015-10-06 15:47:00"
965 | },
966 | {
967 | "name": "phpunit/php-file-iterator",
968 | "version": "1.4.1",
969 | "source": {
970 | "type": "git",
971 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
972 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
973 | },
974 | "dist": {
975 | "type": "zip",
976 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
977 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
978 | "shasum": ""
979 | },
980 | "require": {
981 | "php": ">=5.3.3"
982 | },
983 | "type": "library",
984 | "extra": {
985 | "branch-alias": {
986 | "dev-master": "1.4.x-dev"
987 | }
988 | },
989 | "autoload": {
990 | "classmap": [
991 | "src/"
992 | ]
993 | },
994 | "notification-url": "https://packagist.org/downloads/",
995 | "license": [
996 | "BSD-3-Clause"
997 | ],
998 | "authors": [
999 | {
1000 | "name": "Sebastian Bergmann",
1001 | "email": "sb@sebastian-bergmann.de",
1002 | "role": "lead"
1003 | }
1004 | ],
1005 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
1006 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
1007 | "keywords": [
1008 | "filesystem",
1009 | "iterator"
1010 | ],
1011 | "time": "2015-06-21 13:08:43"
1012 | },
1013 | {
1014 | "name": "phpunit/php-text-template",
1015 | "version": "1.2.1",
1016 | "source": {
1017 | "type": "git",
1018 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
1019 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
1020 | },
1021 | "dist": {
1022 | "type": "zip",
1023 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1024 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1025 | "shasum": ""
1026 | },
1027 | "require": {
1028 | "php": ">=5.3.3"
1029 | },
1030 | "type": "library",
1031 | "autoload": {
1032 | "classmap": [
1033 | "src/"
1034 | ]
1035 | },
1036 | "notification-url": "https://packagist.org/downloads/",
1037 | "license": [
1038 | "BSD-3-Clause"
1039 | ],
1040 | "authors": [
1041 | {
1042 | "name": "Sebastian Bergmann",
1043 | "email": "sebastian@phpunit.de",
1044 | "role": "lead"
1045 | }
1046 | ],
1047 | "description": "Simple template engine.",
1048 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
1049 | "keywords": [
1050 | "template"
1051 | ],
1052 | "time": "2015-06-21 13:50:34"
1053 | },
1054 | {
1055 | "name": "phpunit/php-timer",
1056 | "version": "1.0.7",
1057 | "source": {
1058 | "type": "git",
1059 | "url": "https://github.com/sebastianbergmann/php-timer.git",
1060 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
1061 | },
1062 | "dist": {
1063 | "type": "zip",
1064 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
1065 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
1066 | "shasum": ""
1067 | },
1068 | "require": {
1069 | "php": ">=5.3.3"
1070 | },
1071 | "type": "library",
1072 | "autoload": {
1073 | "classmap": [
1074 | "src/"
1075 | ]
1076 | },
1077 | "notification-url": "https://packagist.org/downloads/",
1078 | "license": [
1079 | "BSD-3-Clause"
1080 | ],
1081 | "authors": [
1082 | {
1083 | "name": "Sebastian Bergmann",
1084 | "email": "sb@sebastian-bergmann.de",
1085 | "role": "lead"
1086 | }
1087 | ],
1088 | "description": "Utility class for timing",
1089 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
1090 | "keywords": [
1091 | "timer"
1092 | ],
1093 | "time": "2015-06-21 08:01:12"
1094 | },
1095 | {
1096 | "name": "phpunit/php-token-stream",
1097 | "version": "1.4.8",
1098 | "source": {
1099 | "type": "git",
1100 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
1101 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
1102 | },
1103 | "dist": {
1104 | "type": "zip",
1105 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
1106 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
1107 | "shasum": ""
1108 | },
1109 | "require": {
1110 | "ext-tokenizer": "*",
1111 | "php": ">=5.3.3"
1112 | },
1113 | "require-dev": {
1114 | "phpunit/phpunit": "~4.2"
1115 | },
1116 | "type": "library",
1117 | "extra": {
1118 | "branch-alias": {
1119 | "dev-master": "1.4-dev"
1120 | }
1121 | },
1122 | "autoload": {
1123 | "classmap": [
1124 | "src/"
1125 | ]
1126 | },
1127 | "notification-url": "https://packagist.org/downloads/",
1128 | "license": [
1129 | "BSD-3-Clause"
1130 | ],
1131 | "authors": [
1132 | {
1133 | "name": "Sebastian Bergmann",
1134 | "email": "sebastian@phpunit.de"
1135 | }
1136 | ],
1137 | "description": "Wrapper around PHP's tokenizer extension.",
1138 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
1139 | "keywords": [
1140 | "tokenizer"
1141 | ],
1142 | "time": "2015-09-15 10:49:45"
1143 | },
1144 | {
1145 | "name": "phpunit/phpunit",
1146 | "version": "4.8.24",
1147 | "source": {
1148 | "type": "git",
1149 | "url": "https://github.com/sebastianbergmann/phpunit.git",
1150 | "reference": "a1066c562c52900a142a0e2bbf0582994671385e"
1151 | },
1152 | "dist": {
1153 | "type": "zip",
1154 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e",
1155 | "reference": "a1066c562c52900a142a0e2bbf0582994671385e",
1156 | "shasum": ""
1157 | },
1158 | "require": {
1159 | "ext-dom": "*",
1160 | "ext-json": "*",
1161 | "ext-pcre": "*",
1162 | "ext-reflection": "*",
1163 | "ext-spl": "*",
1164 | "php": ">=5.3.3",
1165 | "phpspec/prophecy": "^1.3.1",
1166 | "phpunit/php-code-coverage": "~2.1",
1167 | "phpunit/php-file-iterator": "~1.4",
1168 | "phpunit/php-text-template": "~1.2",
1169 | "phpunit/php-timer": ">=1.0.6",
1170 | "phpunit/phpunit-mock-objects": "~2.3",
1171 | "sebastian/comparator": "~1.1",
1172 | "sebastian/diff": "~1.2",
1173 | "sebastian/environment": "~1.3",
1174 | "sebastian/exporter": "~1.2",
1175 | "sebastian/global-state": "~1.0",
1176 | "sebastian/version": "~1.0",
1177 | "symfony/yaml": "~2.1|~3.0"
1178 | },
1179 | "suggest": {
1180 | "phpunit/php-invoker": "~1.1"
1181 | },
1182 | "bin": [
1183 | "phpunit"
1184 | ],
1185 | "type": "library",
1186 | "extra": {
1187 | "branch-alias": {
1188 | "dev-master": "4.8.x-dev"
1189 | }
1190 | },
1191 | "autoload": {
1192 | "classmap": [
1193 | "src/"
1194 | ]
1195 | },
1196 | "notification-url": "https://packagist.org/downloads/",
1197 | "license": [
1198 | "BSD-3-Clause"
1199 | ],
1200 | "authors": [
1201 | {
1202 | "name": "Sebastian Bergmann",
1203 | "email": "sebastian@phpunit.de",
1204 | "role": "lead"
1205 | }
1206 | ],
1207 | "description": "The PHP Unit Testing framework.",
1208 | "homepage": "https://phpunit.de/",
1209 | "keywords": [
1210 | "phpunit",
1211 | "testing",
1212 | "xunit"
1213 | ],
1214 | "time": "2016-03-14 06:16:08"
1215 | },
1216 | {
1217 | "name": "phpunit/phpunit-mock-objects",
1218 | "version": "2.3.8",
1219 | "source": {
1220 | "type": "git",
1221 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
1222 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
1223 | },
1224 | "dist": {
1225 | "type": "zip",
1226 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
1227 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
1228 | "shasum": ""
1229 | },
1230 | "require": {
1231 | "doctrine/instantiator": "^1.0.2",
1232 | "php": ">=5.3.3",
1233 | "phpunit/php-text-template": "~1.2",
1234 | "sebastian/exporter": "~1.2"
1235 | },
1236 | "require-dev": {
1237 | "phpunit/phpunit": "~4.4"
1238 | },
1239 | "suggest": {
1240 | "ext-soap": "*"
1241 | },
1242 | "type": "library",
1243 | "extra": {
1244 | "branch-alias": {
1245 | "dev-master": "2.3.x-dev"
1246 | }
1247 | },
1248 | "autoload": {
1249 | "classmap": [
1250 | "src/"
1251 | ]
1252 | },
1253 | "notification-url": "https://packagist.org/downloads/",
1254 | "license": [
1255 | "BSD-3-Clause"
1256 | ],
1257 | "authors": [
1258 | {
1259 | "name": "Sebastian Bergmann",
1260 | "email": "sb@sebastian-bergmann.de",
1261 | "role": "lead"
1262 | }
1263 | ],
1264 | "description": "Mock Object library for PHPUnit",
1265 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
1266 | "keywords": [
1267 | "mock",
1268 | "xunit"
1269 | ],
1270 | "time": "2015-10-02 06:51:40"
1271 | },
1272 | {
1273 | "name": "ramsey/uuid",
1274 | "version": "3.4.1",
1275 | "source": {
1276 | "type": "git",
1277 | "url": "https://github.com/ramsey/uuid.git",
1278 | "reference": "b4fe3b7387cb323fd15ad5837cae992422c9fa5c"
1279 | },
1280 | "dist": {
1281 | "type": "zip",
1282 | "url": "https://api.github.com/repos/ramsey/uuid/zipball/b4fe3b7387cb323fd15ad5837cae992422c9fa5c",
1283 | "reference": "b4fe3b7387cb323fd15ad5837cae992422c9fa5c",
1284 | "shasum": ""
1285 | },
1286 | "require": {
1287 | "paragonie/random_compat": "^1.0|^2.0",
1288 | "php": ">=5.4"
1289 | },
1290 | "replace": {
1291 | "rhumsaa/uuid": "self.version"
1292 | },
1293 | "require-dev": {
1294 | "apigen/apigen": "^4.1",
1295 | "codeception/aspect-mock": "1.0.0",
1296 | "goaop/framework": "1.0.0-alpha.2",
1297 | "ircmaxell/random-lib": "^1.1",
1298 | "jakub-onderka/php-parallel-lint": "^0.9.0",
1299 | "mockery/mockery": "^0.9.4",
1300 | "moontoast/math": "^1.1",
1301 | "phpunit/phpunit": "^4.7|^5.0",
1302 | "satooshi/php-coveralls": "^0.6.1",
1303 | "squizlabs/php_codesniffer": "^2.3"
1304 | },
1305 | "suggest": {
1306 | "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator",
1307 | "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator",
1308 | "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter",
1309 | "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).",
1310 | "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid",
1311 | "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type."
1312 | },
1313 | "type": "library",
1314 | "extra": {
1315 | "branch-alias": {
1316 | "dev-master": "3.x-dev"
1317 | }
1318 | },
1319 | "autoload": {
1320 | "psr-4": {
1321 | "Ramsey\\Uuid\\": "src/"
1322 | }
1323 | },
1324 | "notification-url": "https://packagist.org/downloads/",
1325 | "license": [
1326 | "MIT"
1327 | ],
1328 | "authors": [
1329 | {
1330 | "name": "Marijn Huizendveld",
1331 | "email": "marijn.huizendveld@gmail.com"
1332 | },
1333 | {
1334 | "name": "Thibaud Fabre",
1335 | "email": "thibaud@aztech.io"
1336 | },
1337 | {
1338 | "name": "Ben Ramsey",
1339 | "email": "ben@benramsey.com",
1340 | "homepage": "https://benramsey.com"
1341 | }
1342 | ],
1343 | "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).",
1344 | "homepage": "https://github.com/ramsey/uuid",
1345 | "keywords": [
1346 | "guid",
1347 | "identifier",
1348 | "uuid"
1349 | ],
1350 | "time": "2016-04-24 00:30:41"
1351 | },
1352 | {
1353 | "name": "ramsey/uuid-doctrine",
1354 | "version": "1.2.0",
1355 | "source": {
1356 | "type": "git",
1357 | "url": "https://github.com/ramsey/uuid-doctrine.git",
1358 | "reference": "503c5e0c22b17fe5a53af53124621360e9e07f41"
1359 | },
1360 | "dist": {
1361 | "type": "zip",
1362 | "url": "https://api.github.com/repos/ramsey/uuid-doctrine/zipball/503c5e0c22b17fe5a53af53124621360e9e07f41",
1363 | "reference": "503c5e0c22b17fe5a53af53124621360e9e07f41",
1364 | "shasum": ""
1365 | },
1366 | "require": {
1367 | "doctrine/orm": "^2.5",
1368 | "php": ">=5.4",
1369 | "ramsey/uuid": "^3.0"
1370 | },
1371 | "require-dev": {
1372 | "jakub-onderka/php-parallel-lint": "^0.9.0",
1373 | "phpunit/phpunit": "^4.7|^5.0",
1374 | "satooshi/php-coveralls": "^0.6.1",
1375 | "squizlabs/php_codesniffer": "^2.3"
1376 | },
1377 | "type": "library",
1378 | "autoload": {
1379 | "psr-4": {
1380 | "Ramsey\\Uuid\\Doctrine\\": "src/"
1381 | }
1382 | },
1383 | "notification-url": "https://packagist.org/downloads/",
1384 | "license": [
1385 | "MIT"
1386 | ],
1387 | "authors": [
1388 | {
1389 | "name": "Marijn Huizendveld",
1390 | "email": "marijn.huizendveld@gmail.com"
1391 | },
1392 | {
1393 | "name": "Ben Ramsey",
1394 | "email": "ben@benramsey.com",
1395 | "homepage": "http://benramsey.com"
1396 | }
1397 | ],
1398 | "description": "Allow the use of a ramsey/uuid UUID as Doctrine field type.",
1399 | "homepage": "https://github.com/ramsey/uuid-doctrine",
1400 | "keywords": [
1401 | "doctrine",
1402 | "guid",
1403 | "identifier",
1404 | "uuid"
1405 | ],
1406 | "time": "2016-03-23 17:44:03"
1407 | },
1408 | {
1409 | "name": "sebastian/comparator",
1410 | "version": "1.2.0",
1411 | "source": {
1412 | "type": "git",
1413 | "url": "https://github.com/sebastianbergmann/comparator.git",
1414 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
1415 | },
1416 | "dist": {
1417 | "type": "zip",
1418 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
1419 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
1420 | "shasum": ""
1421 | },
1422 | "require": {
1423 | "php": ">=5.3.3",
1424 | "sebastian/diff": "~1.2",
1425 | "sebastian/exporter": "~1.2"
1426 | },
1427 | "require-dev": {
1428 | "phpunit/phpunit": "~4.4"
1429 | },
1430 | "type": "library",
1431 | "extra": {
1432 | "branch-alias": {
1433 | "dev-master": "1.2.x-dev"
1434 | }
1435 | },
1436 | "autoload": {
1437 | "classmap": [
1438 | "src/"
1439 | ]
1440 | },
1441 | "notification-url": "https://packagist.org/downloads/",
1442 | "license": [
1443 | "BSD-3-Clause"
1444 | ],
1445 | "authors": [
1446 | {
1447 | "name": "Jeff Welch",
1448 | "email": "whatthejeff@gmail.com"
1449 | },
1450 | {
1451 | "name": "Volker Dusch",
1452 | "email": "github@wallbash.com"
1453 | },
1454 | {
1455 | "name": "Bernhard Schussek",
1456 | "email": "bschussek@2bepublished.at"
1457 | },
1458 | {
1459 | "name": "Sebastian Bergmann",
1460 | "email": "sebastian@phpunit.de"
1461 | }
1462 | ],
1463 | "description": "Provides the functionality to compare PHP values for equality",
1464 | "homepage": "http://www.github.com/sebastianbergmann/comparator",
1465 | "keywords": [
1466 | "comparator",
1467 | "compare",
1468 | "equality"
1469 | ],
1470 | "time": "2015-07-26 15:48:44"
1471 | },
1472 | {
1473 | "name": "sebastian/diff",
1474 | "version": "1.4.1",
1475 | "source": {
1476 | "type": "git",
1477 | "url": "https://github.com/sebastianbergmann/diff.git",
1478 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
1479 | },
1480 | "dist": {
1481 | "type": "zip",
1482 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
1483 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
1484 | "shasum": ""
1485 | },
1486 | "require": {
1487 | "php": ">=5.3.3"
1488 | },
1489 | "require-dev": {
1490 | "phpunit/phpunit": "~4.8"
1491 | },
1492 | "type": "library",
1493 | "extra": {
1494 | "branch-alias": {
1495 | "dev-master": "1.4-dev"
1496 | }
1497 | },
1498 | "autoload": {
1499 | "classmap": [
1500 | "src/"
1501 | ]
1502 | },
1503 | "notification-url": "https://packagist.org/downloads/",
1504 | "license": [
1505 | "BSD-3-Clause"
1506 | ],
1507 | "authors": [
1508 | {
1509 | "name": "Kore Nordmann",
1510 | "email": "mail@kore-nordmann.de"
1511 | },
1512 | {
1513 | "name": "Sebastian Bergmann",
1514 | "email": "sebastian@phpunit.de"
1515 | }
1516 | ],
1517 | "description": "Diff implementation",
1518 | "homepage": "https://github.com/sebastianbergmann/diff",
1519 | "keywords": [
1520 | "diff"
1521 | ],
1522 | "time": "2015-12-08 07:14:41"
1523 | },
1524 | {
1525 | "name": "sebastian/environment",
1526 | "version": "1.3.5",
1527 | "source": {
1528 | "type": "git",
1529 | "url": "https://github.com/sebastianbergmann/environment.git",
1530 | "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf"
1531 | },
1532 | "dist": {
1533 | "type": "zip",
1534 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
1535 | "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
1536 | "shasum": ""
1537 | },
1538 | "require": {
1539 | "php": ">=5.3.3"
1540 | },
1541 | "require-dev": {
1542 | "phpunit/phpunit": "~4.4"
1543 | },
1544 | "type": "library",
1545 | "extra": {
1546 | "branch-alias": {
1547 | "dev-master": "1.3.x-dev"
1548 | }
1549 | },
1550 | "autoload": {
1551 | "classmap": [
1552 | "src/"
1553 | ]
1554 | },
1555 | "notification-url": "https://packagist.org/downloads/",
1556 | "license": [
1557 | "BSD-3-Clause"
1558 | ],
1559 | "authors": [
1560 | {
1561 | "name": "Sebastian Bergmann",
1562 | "email": "sebastian@phpunit.de"
1563 | }
1564 | ],
1565 | "description": "Provides functionality to handle HHVM/PHP environments",
1566 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1567 | "keywords": [
1568 | "Xdebug",
1569 | "environment",
1570 | "hhvm"
1571 | ],
1572 | "time": "2016-02-26 18:40:46"
1573 | },
1574 | {
1575 | "name": "sebastian/exporter",
1576 | "version": "1.2.1",
1577 | "source": {
1578 | "type": "git",
1579 | "url": "https://github.com/sebastianbergmann/exporter.git",
1580 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e"
1581 | },
1582 | "dist": {
1583 | "type": "zip",
1584 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
1585 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e",
1586 | "shasum": ""
1587 | },
1588 | "require": {
1589 | "php": ">=5.3.3",
1590 | "sebastian/recursion-context": "~1.0"
1591 | },
1592 | "require-dev": {
1593 | "phpunit/phpunit": "~4.4"
1594 | },
1595 | "type": "library",
1596 | "extra": {
1597 | "branch-alias": {
1598 | "dev-master": "1.2.x-dev"
1599 | }
1600 | },
1601 | "autoload": {
1602 | "classmap": [
1603 | "src/"
1604 | ]
1605 | },
1606 | "notification-url": "https://packagist.org/downloads/",
1607 | "license": [
1608 | "BSD-3-Clause"
1609 | ],
1610 | "authors": [
1611 | {
1612 | "name": "Jeff Welch",
1613 | "email": "whatthejeff@gmail.com"
1614 | },
1615 | {
1616 | "name": "Volker Dusch",
1617 | "email": "github@wallbash.com"
1618 | },
1619 | {
1620 | "name": "Bernhard Schussek",
1621 | "email": "bschussek@2bepublished.at"
1622 | },
1623 | {
1624 | "name": "Sebastian Bergmann",
1625 | "email": "sebastian@phpunit.de"
1626 | },
1627 | {
1628 | "name": "Adam Harvey",
1629 | "email": "aharvey@php.net"
1630 | }
1631 | ],
1632 | "description": "Provides the functionality to export PHP variables for visualization",
1633 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1634 | "keywords": [
1635 | "export",
1636 | "exporter"
1637 | ],
1638 | "time": "2015-06-21 07:55:53"
1639 | },
1640 | {
1641 | "name": "sebastian/global-state",
1642 | "version": "1.1.1",
1643 | "source": {
1644 | "type": "git",
1645 | "url": "https://github.com/sebastianbergmann/global-state.git",
1646 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1647 | },
1648 | "dist": {
1649 | "type": "zip",
1650 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1651 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1652 | "shasum": ""
1653 | },
1654 | "require": {
1655 | "php": ">=5.3.3"
1656 | },
1657 | "require-dev": {
1658 | "phpunit/phpunit": "~4.2"
1659 | },
1660 | "suggest": {
1661 | "ext-uopz": "*"
1662 | },
1663 | "type": "library",
1664 | "extra": {
1665 | "branch-alias": {
1666 | "dev-master": "1.0-dev"
1667 | }
1668 | },
1669 | "autoload": {
1670 | "classmap": [
1671 | "src/"
1672 | ]
1673 | },
1674 | "notification-url": "https://packagist.org/downloads/",
1675 | "license": [
1676 | "BSD-3-Clause"
1677 | ],
1678 | "authors": [
1679 | {
1680 | "name": "Sebastian Bergmann",
1681 | "email": "sebastian@phpunit.de"
1682 | }
1683 | ],
1684 | "description": "Snapshotting of global state",
1685 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1686 | "keywords": [
1687 | "global state"
1688 | ],
1689 | "time": "2015-10-12 03:26:01"
1690 | },
1691 | {
1692 | "name": "sebastian/recursion-context",
1693 | "version": "1.0.2",
1694 | "source": {
1695 | "type": "git",
1696 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1697 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
1698 | },
1699 | "dist": {
1700 | "type": "zip",
1701 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
1702 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
1703 | "shasum": ""
1704 | },
1705 | "require": {
1706 | "php": ">=5.3.3"
1707 | },
1708 | "require-dev": {
1709 | "phpunit/phpunit": "~4.4"
1710 | },
1711 | "type": "library",
1712 | "extra": {
1713 | "branch-alias": {
1714 | "dev-master": "1.0.x-dev"
1715 | }
1716 | },
1717 | "autoload": {
1718 | "classmap": [
1719 | "src/"
1720 | ]
1721 | },
1722 | "notification-url": "https://packagist.org/downloads/",
1723 | "license": [
1724 | "BSD-3-Clause"
1725 | ],
1726 | "authors": [
1727 | {
1728 | "name": "Jeff Welch",
1729 | "email": "whatthejeff@gmail.com"
1730 | },
1731 | {
1732 | "name": "Sebastian Bergmann",
1733 | "email": "sebastian@phpunit.de"
1734 | },
1735 | {
1736 | "name": "Adam Harvey",
1737 | "email": "aharvey@php.net"
1738 | }
1739 | ],
1740 | "description": "Provides functionality to recursively process PHP variables",
1741 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1742 | "time": "2015-11-11 19:50:13"
1743 | },
1744 | {
1745 | "name": "sebastian/version",
1746 | "version": "1.0.6",
1747 | "source": {
1748 | "type": "git",
1749 | "url": "https://github.com/sebastianbergmann/version.git",
1750 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1751 | },
1752 | "dist": {
1753 | "type": "zip",
1754 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1755 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1756 | "shasum": ""
1757 | },
1758 | "type": "library",
1759 | "autoload": {
1760 | "classmap": [
1761 | "src/"
1762 | ]
1763 | },
1764 | "notification-url": "https://packagist.org/downloads/",
1765 | "license": [
1766 | "BSD-3-Clause"
1767 | ],
1768 | "authors": [
1769 | {
1770 | "name": "Sebastian Bergmann",
1771 | "email": "sebastian@phpunit.de",
1772 | "role": "lead"
1773 | }
1774 | ],
1775 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1776 | "homepage": "https://github.com/sebastianbergmann/version",
1777 | "time": "2015-06-21 13:59:46"
1778 | },
1779 | {
1780 | "name": "symfony/console",
1781 | "version": "v3.0.4",
1782 | "source": {
1783 | "type": "git",
1784 | "url": "https://github.com/symfony/console.git",
1785 | "reference": "6b1175135bc2a74c08a28d89761272de8beed8cd"
1786 | },
1787 | "dist": {
1788 | "type": "zip",
1789 | "url": "https://api.github.com/repos/symfony/console/zipball/6b1175135bc2a74c08a28d89761272de8beed8cd",
1790 | "reference": "6b1175135bc2a74c08a28d89761272de8beed8cd",
1791 | "shasum": ""
1792 | },
1793 | "require": {
1794 | "php": ">=5.5.9",
1795 | "symfony/polyfill-mbstring": "~1.0"
1796 | },
1797 | "require-dev": {
1798 | "psr/log": "~1.0",
1799 | "symfony/event-dispatcher": "~2.8|~3.0",
1800 | "symfony/process": "~2.8|~3.0"
1801 | },
1802 | "suggest": {
1803 | "psr/log": "For using the console logger",
1804 | "symfony/event-dispatcher": "",
1805 | "symfony/process": ""
1806 | },
1807 | "type": "library",
1808 | "extra": {
1809 | "branch-alias": {
1810 | "dev-master": "3.0-dev"
1811 | }
1812 | },
1813 | "autoload": {
1814 | "psr-4": {
1815 | "Symfony\\Component\\Console\\": ""
1816 | },
1817 | "exclude-from-classmap": [
1818 | "/Tests/"
1819 | ]
1820 | },
1821 | "notification-url": "https://packagist.org/downloads/",
1822 | "license": [
1823 | "MIT"
1824 | ],
1825 | "authors": [
1826 | {
1827 | "name": "Fabien Potencier",
1828 | "email": "fabien@symfony.com"
1829 | },
1830 | {
1831 | "name": "Symfony Community",
1832 | "homepage": "https://symfony.com/contributors"
1833 | }
1834 | ],
1835 | "description": "Symfony Console Component",
1836 | "homepage": "https://symfony.com",
1837 | "time": "2016-03-16 17:00:50"
1838 | },
1839 | {
1840 | "name": "symfony/polyfill-mbstring",
1841 | "version": "v1.1.1",
1842 | "source": {
1843 | "type": "git",
1844 | "url": "https://github.com/symfony/polyfill-mbstring.git",
1845 | "reference": "1289d16209491b584839022f29257ad859b8532d"
1846 | },
1847 | "dist": {
1848 | "type": "zip",
1849 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
1850 | "reference": "1289d16209491b584839022f29257ad859b8532d",
1851 | "shasum": ""
1852 | },
1853 | "require": {
1854 | "php": ">=5.3.3"
1855 | },
1856 | "suggest": {
1857 | "ext-mbstring": "For best performance"
1858 | },
1859 | "type": "library",
1860 | "extra": {
1861 | "branch-alias": {
1862 | "dev-master": "1.1-dev"
1863 | }
1864 | },
1865 | "autoload": {
1866 | "psr-4": {
1867 | "Symfony\\Polyfill\\Mbstring\\": ""
1868 | },
1869 | "files": [
1870 | "bootstrap.php"
1871 | ]
1872 | },
1873 | "notification-url": "https://packagist.org/downloads/",
1874 | "license": [
1875 | "MIT"
1876 | ],
1877 | "authors": [
1878 | {
1879 | "name": "Nicolas Grekas",
1880 | "email": "p@tchwork.com"
1881 | },
1882 | {
1883 | "name": "Symfony Community",
1884 | "homepage": "https://symfony.com/contributors"
1885 | }
1886 | ],
1887 | "description": "Symfony polyfill for the Mbstring extension",
1888 | "homepage": "https://symfony.com",
1889 | "keywords": [
1890 | "compatibility",
1891 | "mbstring",
1892 | "polyfill",
1893 | "portable",
1894 | "shim"
1895 | ],
1896 | "time": "2016-01-20 09:13:37"
1897 | },
1898 | {
1899 | "name": "symfony/yaml",
1900 | "version": "v3.0.4",
1901 | "source": {
1902 | "type": "git",
1903 | "url": "https://github.com/symfony/yaml.git",
1904 | "reference": "0047c8366744a16de7516622c5b7355336afae96"
1905 | },
1906 | "dist": {
1907 | "type": "zip",
1908 | "url": "https://api.github.com/repos/symfony/yaml/zipball/0047c8366744a16de7516622c5b7355336afae96",
1909 | "reference": "0047c8366744a16de7516622c5b7355336afae96",
1910 | "shasum": ""
1911 | },
1912 | "require": {
1913 | "php": ">=5.5.9"
1914 | },
1915 | "type": "library",
1916 | "extra": {
1917 | "branch-alias": {
1918 | "dev-master": "3.0-dev"
1919 | }
1920 | },
1921 | "autoload": {
1922 | "psr-4": {
1923 | "Symfony\\Component\\Yaml\\": ""
1924 | },
1925 | "exclude-from-classmap": [
1926 | "/Tests/"
1927 | ]
1928 | },
1929 | "notification-url": "https://packagist.org/downloads/",
1930 | "license": [
1931 | "MIT"
1932 | ],
1933 | "authors": [
1934 | {
1935 | "name": "Fabien Potencier",
1936 | "email": "fabien@symfony.com"
1937 | },
1938 | {
1939 | "name": "Symfony Community",
1940 | "homepage": "https://symfony.com/contributors"
1941 | }
1942 | ],
1943 | "description": "Symfony Yaml Component",
1944 | "homepage": "https://symfony.com",
1945 | "time": "2016-03-04 07:55:57"
1946 | },
1947 | {
1948 | "name": "zendframework/zend-code",
1949 | "version": "2.6.3",
1950 | "source": {
1951 | "type": "git",
1952 | "url": "https://github.com/zendframework/zend-code.git",
1953 | "reference": "95033f061b083e16cdee60530ec260d7d628b887"
1954 | },
1955 | "dist": {
1956 | "type": "zip",
1957 | "url": "https://api.github.com/repos/zendframework/zend-code/zipball/95033f061b083e16cdee60530ec260d7d628b887",
1958 | "reference": "95033f061b083e16cdee60530ec260d7d628b887",
1959 | "shasum": ""
1960 | },
1961 | "require": {
1962 | "php": "^5.5 || 7.0.0 - 7.0.4 || ^7.0.6",
1963 | "zendframework/zend-eventmanager": "^2.6 || ^3.0"
1964 | },
1965 | "require-dev": {
1966 | "doctrine/annotations": "~1.0",
1967 | "fabpot/php-cs-fixer": "1.7.*",
1968 | "phpunit/phpunit": "^4.8.21",
1969 | "zendframework/zend-stdlib": "^2.7 || ^3.0"
1970 | },
1971 | "suggest": {
1972 | "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features",
1973 | "zendframework/zend-stdlib": "Zend\\Stdlib component"
1974 | },
1975 | "type": "library",
1976 | "extra": {
1977 | "branch-alias": {
1978 | "dev-master": "2.6-dev",
1979 | "dev-develop": "2.7-dev"
1980 | }
1981 | },
1982 | "autoload": {
1983 | "psr-4": {
1984 | "Zend\\Code\\": "src/"
1985 | }
1986 | },
1987 | "notification-url": "https://packagist.org/downloads/",
1988 | "license": [
1989 | "BSD-3-Clause"
1990 | ],
1991 | "description": "provides facilities to generate arbitrary code using an object oriented interface",
1992 | "homepage": "https://github.com/zendframework/zend-code",
1993 | "keywords": [
1994 | "code",
1995 | "zf2"
1996 | ],
1997 | "time": "2016-04-20 17:26:42"
1998 | },
1999 | {
2000 | "name": "zendframework/zend-eventmanager",
2001 | "version": "3.0.1",
2002 | "source": {
2003 | "type": "git",
2004 | "url": "https://github.com/zendframework/zend-eventmanager.git",
2005 | "reference": "5c80bdee0e952be112dcec0968bad770082c3a6e"
2006 | },
2007 | "dist": {
2008 | "type": "zip",
2009 | "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/5c80bdee0e952be112dcec0968bad770082c3a6e",
2010 | "reference": "5c80bdee0e952be112dcec0968bad770082c3a6e",
2011 | "shasum": ""
2012 | },
2013 | "require": {
2014 | "php": "^5.5 || ^7.0"
2015 | },
2016 | "require-dev": {
2017 | "athletic/athletic": "^0.1",
2018 | "container-interop/container-interop": "^1.1.0",
2019 | "phpunit/phpunit": "~4.0",
2020 | "squizlabs/php_codesniffer": "^2.0",
2021 | "zendframework/zend-stdlib": "^2.7.3 || ^3.0"
2022 | },
2023 | "suggest": {
2024 | "container-interop/container-interop": "^1.1.0, to use the lazy listeners feature",
2025 | "zendframework/zend-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature"
2026 | },
2027 | "type": "library",
2028 | "extra": {
2029 | "branch-alias": {
2030 | "dev-master": "3.0-dev",
2031 | "dev-develop": "3.1-dev"
2032 | }
2033 | },
2034 | "autoload": {
2035 | "psr-4": {
2036 | "Zend\\EventManager\\": "src/"
2037 | }
2038 | },
2039 | "notification-url": "https://packagist.org/downloads/",
2040 | "license": [
2041 | "BSD-3-Clause"
2042 | ],
2043 | "description": "Trigger and listen to events within a PHP application",
2044 | "homepage": "https://github.com/zendframework/zend-eventmanager",
2045 | "keywords": [
2046 | "event",
2047 | "eventmanager",
2048 | "events",
2049 | "zf2"
2050 | ],
2051 | "time": "2016-02-18 20:53:00"
2052 | }
2053 | ],
2054 | "packages-dev": [],
2055 | "aliases": [],
2056 | "minimum-stability": "stable",
2057 | "stability-flags": [],
2058 | "prefer-stable": false,
2059 | "prefer-lowest": false,
2060 | "platform": [],
2061 | "platform-dev": [],
2062 | "platform-overrides": {
2063 | "php": "5.5.9"
2064 | }
2065 | }
2066 |
--------------------------------------------------------------------------------
/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 | !proxies
--------------------------------------------------------------------------------
/data/proxies/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/mapping/Authentication.Entity.User.dcm.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/mapping/Enforcement.Entity.EnforcementRequest.dcm.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/mapping/Library.BookAmount.dcm.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 | Maintainable Doctrine apps tutorial
8 |
9 | DoctrineMigrations
10 | ./migrations
11 |
12 |
--------------------------------------------------------------------------------
/migrations/Version20160428103311.php:
--------------------------------------------------------------------------------
1 | abortIf($this->connection->getDatabasePlatform()->getName() != 'sqlite', 'Migration can only be executed safely on \'sqlite\'.');
20 |
21 | $this->addSql('CREATE TABLE User (id CHAR(36) NOT NULL, PRIMARY KEY(id))');
22 | $this->addSql('CREATE TABLE EnforcementRequest (id CHAR(36) NOT NULL, PRIMARY KEY(id))');
23 | $this->addSql('CREATE TABLE BookAmount (isbn VARCHAR(255) NOT NULL, amount INTEGER NOT NULL, libraryId VARCHAR(255) NOT NULL, PRIMARY KEY(libraryId, isbn))');
24 | }
25 |
26 | /**
27 | * @param Schema $schema
28 | */
29 | public function down(Schema $schema)
30 | {
31 | // this down() migration is auto-generated, please modify it to your needs
32 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'sqlite', 'Migration can only be executed safely on \'sqlite\'.');
33 |
34 | $this->addSql('DROP TABLE User');
35 | $this->addSql('DROP TABLE EnforcementRequest');
36 | $this->addSql('DROP TABLE BookAmount');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 | ./test
17 |
18 |
19 |
20 | ./src
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/public/add-book.php:
--------------------------------------------------------------------------------
1 | find(User::class, $_GET['userId']);
12 |
13 | $_SESSION['userId'] = (string) $user->getId();
14 |
--------------------------------------------------------------------------------
/public/lend-book-to-user.php:
--------------------------------------------------------------------------------
1 | id = Uuid::uuid4();
17 | }
18 |
19 | /**
20 | * @return \Ramsey\Uuid\UuidInterface
21 | */
22 | public function getId()
23 | {
24 | return $this->id;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/DoctrineIntegration/Library/AmountType.php:
--------------------------------------------------------------------------------
1 | toInt(), $platform);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/DoctrineIntegration/Library/ISBNType.php:
--------------------------------------------------------------------------------
1 | id = Uuid::uuid4();
17 | }
18 |
19 | /**
20 | * @return \Ramsey\Uuid\UuidInterface
21 | */
22 | public function getId()
23 | {
24 | return $this->id;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Library/Amount.php:
--------------------------------------------------------------------------------
1 | amount = $amount;
32 |
33 | return $instance;
34 | }
35 |
36 | public function add(Amount $other)
37 | {
38 | $instance = new self();
39 |
40 | $instance->amount = $this->amount + $other->amount;
41 |
42 | return $instance;
43 | }
44 |
45 | public function toInt()
46 | {
47 | return $this->amount;
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Library/Book.php:
--------------------------------------------------------------------------------
1 | libraryId = $libraryId;
15 | $this->isbn = $isbn;
16 | $this->amount = $amount;
17 | }
18 |
19 | public function add(Amount $amount)
20 | {
21 | $this->amount = $this->amount->add($amount);
22 |
23 | return $this;
24 | }
25 |
26 | public function getLibraryId()
27 | {
28 | return $this->libraryId;
29 | }
30 |
31 | public function getIsbn()
32 | {
33 | return $this->isbn;
34 | }
35 |
36 | public function toAmount()
37 | {
38 | return $this->amount;
39 | }
40 |
41 | public function toInt()
42 | {
43 | return $this->amount->toInt();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Library/Command/AddBook.php:
--------------------------------------------------------------------------------
1 | libraryId = $libraryId;
32 | $this->isbn = $isbn;
33 | $this->amount = $amount;
34 | }
35 |
36 | /**
37 | * @return LibraryId
38 | */
39 | public function getLibraryId()
40 | {
41 | return $this->libraryId;
42 | }
43 |
44 | /**
45 | * @return ISBN
46 | */
47 | public function getIsbn()
48 | {
49 | return $this->isbn;
50 | }
51 |
52 | /**
53 | * @return Amount
54 | */
55 | public function getAmount()
56 | {
57 | return $this->amount;
58 | }
59 | }
--------------------------------------------------------------------------------
/src/Library/DoctrineLibraryRepository.php:
--------------------------------------------------------------------------------
1 | bookAmountRepository = $bookAmountRepository;
25 | $this->objectManager = $objectManager;
26 | }
27 |
28 | /**
29 | * {@inheritDoc}
30 | */
31 | public function getAmount(LibraryId $libraryId, $isbn)
32 | {
33 | return $this->getOrCreateAmount($libraryId, $isbn);
34 | }
35 |
36 | public function setAmount(LibraryId $libraryId, BookAmount $amount)
37 | {
38 | $this->objectManager->persist($amount);
39 | $this->objectManager->flush();
40 | }
41 |
42 | private function getOrCreateAmount(LibraryId $libraryId, $isbn)
43 | {
44 | $bookAmount = $this->bookAmountRepository->findOneBy([
45 | 'libraryId' => $libraryId,
46 | 'isbn' => $isbn,
47 | ]);
48 |
49 | return $bookAmount instanceof BookAmount
50 | ? $bookAmount
51 | : new BookAmount($libraryId, $isbn, Amount::fromInteger(0));
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Library/ISBN.php:
--------------------------------------------------------------------------------
1 | isbn = $isbn;
22 | }
23 |
24 | public static function fromInt($intIsbn)
25 | {
26 | if (! is_int($intIsbn)) {
27 | throw new \InvalidArgumentException(sprintf(
28 | 'Provided ISBN expected to be int, %s given',
29 | gettype($intIsbn)
30 | ));
31 | }
32 |
33 | if (13 !== strlen((string) $intIsbn)) {
34 | throw new \InvalidArgumentException(sprintf(
35 | 'Provided ISBN is supposed to be composed of 13 integers, %s provided instead',
36 | $intIsbn
37 | ));
38 | }
39 |
40 | return new self($intIsbn);
41 | }
42 |
43 | public static function fromString($stringIsbn)
44 | {
45 | return self::fromInt((int) $stringIsbn);
46 | }
47 |
48 | public function __toString()
49 | {
50 | return (string) $this->isbn;
51 | }
52 | }
--------------------------------------------------------------------------------
/src/Library/LentBook.php:
--------------------------------------------------------------------------------
1 | libraryId = $libraryId;
20 | $this->isbn = $isbn;
21 | $this->userId = $userId;
22 | $this->lentDate = $lentDate;
23 | }
24 |
25 | public function return(\DateTimeImmutable $returnDate)
26 | {
27 | // $returnDate > $this->lentDate
28 | // $this->returnDate === null
29 | $this->returnedDate = $returnDate;
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Library/Library.php:
--------------------------------------------------------------------------------
1 | libraryId = $libraryId;
31 | $this->repository = $repository;
32 | //$this->exclusionPolicy = $exclusionPolicy;
33 | //$this->lentBooks = $lentBooks;
34 | }
35 |
36 | public function addBook($isbn, $amount)
37 | {
38 | $currentAmount = $this->repository->getAmount($this->libraryId, $isbn);
39 |
40 | $this->repository->setAmount($this->libraryId, $currentAmount->add($amount));
41 | }
42 |
43 | public function getBookAmount($isbn)
44 | {
45 | return $this->repository->getAmount($this->libraryId, $isbn)->toInt();
46 | }
47 |
48 | public function lend(ISBN $isbn, UserId $userId, \DateTimeImmutable $lendStartTime)
49 | {
50 | $this->exclusionPolicy->assertUserCanLend($userId, $this->libraryId);
51 |
52 | if (! $amount = $this->getBookAmount($isbn)) {
53 | throw new \OutOfBoundsException(sprintf('Book "%s" is not available', $isbn));
54 | }
55 |
56 | if (($amount - $this->lentBooks->countByIsbnAndLibrary($isbn, $this->libraryId)) <= 0) {
57 | throw new \OutOfBoundsException(sprintf('Book "%s" is currently not available, all books already lent', $isbn));
58 | }
59 |
60 | $this->lentBooks->add(new LentBook($this->libraryId, $isbn, $userId, $lendStartTime));
61 | }
62 |
63 | public function returnLentBook(ISBN $isbn, UserId $userId, \DateTimeImmutable $returnTime)
64 | {
65 | /* @var $lent LentBook */
66 | $lent = $this->lentBooks->get($this->libraryId, $isbn, $userId);
67 |
68 | $this->lentBooks->add($lent->return($returnTime));
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/Library/LibraryId.php:
--------------------------------------------------------------------------------
1 | id = Uuid::uuid4();
24 |
25 | return $instance;
26 | }
27 |
28 | public static function fromString($stringId)
29 | {
30 | $instance = new self();
31 |
32 | $instance->id = Uuid::fromString($stringId);
33 |
34 | return $instance;
35 | }
36 |
37 | public function __toString()
38 | {
39 | return (string) $this->id;
40 | }
41 | }
--------------------------------------------------------------------------------
/src/Library/LibraryRepository.php:
--------------------------------------------------------------------------------
1 | id = Uuid::fromString($stringId);
24 |
25 | return $instance;
26 | }
27 |
28 | public function __toString()
29 | {
30 | return (string) $this->id;
31 | }
32 | }
--------------------------------------------------------------------------------
/test/DoctrineIntegration/BookAmountPersistenceTest.php:
--------------------------------------------------------------------------------
1 | setMetadataDriverImpl(new XmlDriver([__DIR__ . '/../../mapping']));
39 |
40 | $configuration->setProxyDir(__DIR__ . '/../../data/proxies');
41 | $configuration->setProxyNamespace('DoctrineProxies');
42 |
43 | $configuration->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_ALWAYS);
44 |
45 | Type::addType(UuidType::class, UuidType::class);
46 | Type::addType(AmountType::class, AmountType::class);
47 | Type::addType(ISBNType::class, ISBNType::class);
48 | Type::addType(LibraryIdType::class, LibraryIdType::class);
49 |
50 | $this->em = EntityManager::create(
51 | [
52 | 'driverClass' => Driver::class,
53 | 'memory' => true,
54 | ],
55 | $configuration
56 | );
57 |
58 | (new SchemaTool($this->em))->createSchema($this->em->getMetadataFactory()->getAllMetadata());
59 | }
60 |
61 | public function testCanPersistABookAmount()
62 | {
63 | $libraryId = LibraryId::newLibraryId();
64 | $isbn = ISBN::fromInt(1111111111111);
65 |
66 | $this->em->persist(new BookAmount($libraryId, $isbn, Amount::fromInteger(3)));
67 | $this->em->flush();
68 |
69 | $this->em->clear();
70 |
71 | /* @var $bookAmount BookAmount */
72 | $bookAmount = $this->em->find(BookAmount::class, ['libraryId' => $libraryId, 'isbn' => $isbn]);
73 |
74 | self::assertInstanceOf(BookAmount::class, $bookAmount);
75 | self::assertInstanceOf(LibraryId::class, $bookAmount->getLibraryId());
76 | self::assertEquals($libraryId, $bookAmount->getLibraryId());
77 | self::assertInstanceOf(ISBN::class, $bookAmount->getIsbn());
78 | self::assertEquals($isbn, $bookAmount->getIsbn());
79 | }
80 | }
--------------------------------------------------------------------------------
/test/Library/AmountTest.php:
--------------------------------------------------------------------------------
1 | toInt());
18 | }
19 |
20 | public function testRejectsNonIntAmounts()
21 | {
22 | $this->setExpectedException(\InvalidArgumentException::class);
23 |
24 | Amount::fromInteger('foo');
25 | }
26 |
27 | public function testRejectsZeroAmount()
28 | {
29 | $this->setExpectedException(\InvalidArgumentException::class);
30 |
31 | Amount::fromInteger(0);
32 | }
33 |
34 | public function testRejectsNegativeAmount()
35 | {
36 | $this->setExpectedException(\InvalidArgumentException::class);
37 |
38 | Amount::fromInteger(-1);
39 | }
40 |
41 | public function testAdd()
42 | {
43 | $intAmount1 = mt_rand(100, 200);
44 | $intAmount2 = mt_rand(100, 200);
45 | $amount1 = Amount::fromInteger($intAmount1);
46 | $amount2 = Amount::fromInteger($intAmount2);
47 |
48 | $sum = $amount1->add($amount2);
49 |
50 | self::assertNotEquals($sum, $intAmount1);
51 | self::assertNotEquals($sum, $intAmount2);
52 | self::assertInstanceOf(Amount::class, $sum);
53 | self::assertSame($intAmount1 + $intAmount2, $sum->toInt());
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/test/Library/DoctrineLibraryRepositoryTest.php:
--------------------------------------------------------------------------------
1 | doctrineRepository = $this->getMock(ObjectRepository::class);
40 | $this->objectManager = $this->getMock(ObjectManager::class);
41 | $this->repository = new DoctrineLibraryRepository($this->doctrineRepository, $this->objectManager);
42 | }
43 |
44 | public function testGetAmountWithNonExistingAmount()
45 | {
46 | $libraryId = (string) Uuid::uuid4();
47 | $isbn = mt_rand(1234567890000, 1234567890123);
48 |
49 | // @TODO what do we do here?
50 | self::assertEquals(new BookAmount(LibraryId::fromString($libraryId), $isbn, Amount::fromInteger(0)), $this->repository->getAmount(LibraryId::fromString($libraryId), $isbn));
51 | }
52 |
53 | public function testGetAmountWithNonMatchingAmountTypeReturned()
54 | {
55 | $libraryId = (string) Uuid::uuid4();
56 | $isbn = mt_rand(1234567890000, 1234567890123);
57 |
58 | $this->doctrineRepository->expects(self::any())->method('findOneBy')->willReturn(new \stdClass());
59 |
60 | // @TODO what do we do here?
61 | self::assertEquals(new BookAmount(LibraryId::fromString($libraryId), $isbn, Amount::fromInteger(0)), $this->repository->getAmount(LibraryId::fromString($libraryId), $isbn));
62 | }
63 |
64 | public function testGetAmountWithFoundAmountOnThePersistenceLayer()
65 | {
66 | $libraryId = (string) Uuid::uuid4();
67 | $isbn = mt_rand(1234567890000, 1234567890123);
68 |
69 | $bookAmount = new BookAmount(LibraryId::fromString($libraryId), $isbn, Amount::fromInteger(mt_rand(100, 200)));
70 |
71 | $this->doctrineRepository->expects(self::any())->method('findOneBy')->willReturn($bookAmount);
72 |
73 | self::assertEquals($bookAmount, $this->repository->getAmount(LibraryId::fromString($libraryId), $isbn));
74 | }
75 |
76 | public function testSetAmount()
77 | {
78 | $bookAmount = new BookAmount(LibraryId::newLibraryId(), 1234567890123, Amount::fromInteger(mt_rand(100, 200)));
79 |
80 | $this->objectManager->expects(self::once())->method('persist')->with($bookAmount);
81 | $this->objectManager->expects(self::once())->method('flush');
82 |
83 | $this->repository->setAmount(LibraryId::newLibraryId(), $bookAmount);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/test/Library/ISBNTest.php:
--------------------------------------------------------------------------------
1 | setExpectedException(\InvalidArgumentException::class);
28 |
29 | ISBN::fromInt($invalidIsbn);
30 | }
31 |
32 | /**
33 | * @dataProvider invalidIntIsbnProvider
34 | *
35 | * @param mixed $invalidIsbn
36 | */
37 | public function testWithInvalidString($invalidIsbn)
38 | {
39 | $this->setExpectedException(\InvalidArgumentException::class);
40 |
41 | ISBN::fromString((string) $invalidIsbn);
42 | }
43 |
44 | public function invalidIntIsbnProvider()
45 | {
46 | return [
47 | [999999999999],
48 | [10000000000000],
49 | ['aaaaaaaaaaaaa'],
50 | ];
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/test/Library/LibraryIdTest.php:
--------------------------------------------------------------------------------
1 | getMock(LibraryRepository::class);
19 |
20 | $library = new Library(LibraryId::fromString($libraryId), $libraryRepository);
21 |
22 | $isbn = mt_rand(1234567890000, 1234567890123);
23 | $previousAmount = mt_rand(100, 200);
24 | $amount = mt_rand(100, 200);
25 |
26 | $libraryRepository
27 | ->expects(self::any())
28 | ->method('getAmount')
29 | ->with($libraryId, $isbn)
30 | ->willReturn(new BookAmount(LibraryId::fromString($libraryId), $isbn, Amount::fromInteger($previousAmount)));
31 | $libraryRepository->expects(self::once())->method('setAmount')->with(
32 | $libraryId,
33 | self::callback(function (BookAmount $setAmount) use ($previousAmount, $amount, $isbn) {
34 | self::assertSame($previousAmount + $amount, $setAmount->toInt());
35 | self::assertEquals($isbn, $setAmount->getIsbn());
36 |
37 | return true;
38 | })
39 | );
40 |
41 | $library->addBook($isbn, Amount::fromInteger($amount));
42 | }
43 |
44 | public function testWillGetBooksFromTheLibrary()
45 | {
46 | $libraryId = (string) Uuid::uuid4();
47 | /* @var $libraryRepository LibraryRepository|\PHPUnit_Framework_MockObject_MockObject */
48 | $libraryRepository = $this->getMock(LibraryRepository::class);
49 |
50 | $library = new Library(LibraryId::fromString($libraryId), $libraryRepository);
51 |
52 | $isbn = mt_rand(1234567890000, 1234567890123);
53 | $amount = mt_rand(100, 200);
54 |
55 | $bookAmount = new BookAmount(LibraryId::fromString($libraryId), $isbn, Amount::fromInteger($amount));
56 |
57 | $libraryRepository->expects(self::any())->method('getAmount')->with($libraryId, $isbn)->willReturn($bookAmount);
58 |
59 | self::assertSame($amount, $library->getBookAmount($isbn, $amount));
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/test/Library/UserIdTest.php:
--------------------------------------------------------------------------------
1 |