├── .gitignore ├── .styleci.yml ├── .travis.yml ├── changelog.md ├── composer.json ├── composer.lock ├── config └── modelmerge.php ├── contributing.md ├── license.md ├── phpunit-travis.xml ├── phpunit.xml ├── readme.md ├── src ├── Exceptions │ ├── ModelsBelongToDivergedParentsException.php │ └── ModelsNotDupeException.php ├── Facades │ └── ModelMerge.php ├── ModelMerge.php ├── ModelMergeServiceProvider.php └── Strategies │ ├── MergeSimple.php │ └── ModelMergeStrategy.php └── tests ├── BaseTestCase.php ├── DummyContact.php ├── DummySheep.php ├── ModelMergeFacadeTest.php ├── ModelMergeRelationshipsTest.php ├── ModelMergeStrategiesTest.php ├── ModelMergeTest.php └── bootstrap.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: laravel -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - '7.1' 5 | - '7.2' 6 | - '7.3' 7 | env: 8 | matrix: 9 | - PREFER_LOWEST="--prefer-lowest --prefer-stable" 10 | - PREFER_LOWEST="" 11 | 12 | before_install: 13 | - composer install --dev 14 | 15 | before_script: 16 | - composer update $PREFER_LOWEST 17 | - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter 18 | - chmod +x ./cc-test-reporter 19 | - ./cc-test-reporter before-build 20 | 21 | script: 22 | - ./vendor/bin/phpunit --coverage-clover ./build/logs/clover.xml --configuration phpunit-travis.xml 23 | 24 | after_script: 25 | - mv build/logs/clover.xml clover.xml 26 | - ./cc-test-reporter after-build --coverage-input-type clover --id $CODECLIMATE_REPO_TOKEN --exit-code $TRAVIS_TEST_RESULT 27 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `ModelMerge` will be documented in this file. 4 | 5 | ## Version 1.0 6 | 7 | ### Added 8 | - Everything 9 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alariva/modelmerge", 3 | "description": "A Laravel package for Merging Eloquent Models", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Ariel Vallese", 8 | "email": "alariva@gmail.com", 9 | "homepage": "https://alariva.com" 10 | } 11 | ], 12 | "homepage": "https://github.com/alariva/laravel-modelmerge", 13 | "keywords": ["Laravel", "ModelMerge"], 14 | "require": { 15 | "illuminate/support": "~5", 16 | "illuminate/database": "~5" 17 | }, 18 | "require-dev": { 19 | "phpunit/phpunit": "~6.0", 20 | "orchestra/testbench": "~3.5" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Alariva\\ModelMerge\\": "src/" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "psr-4": { 29 | "Alariva\\ModelMerge\\Tests\\": "tests" 30 | } 31 | }, 32 | "extra": { 33 | "laravel": { 34 | "providers": [ 35 | "Alariva\\ModelMerge\\ModelMergeServiceProvider" 36 | ], 37 | "aliases": { 38 | "ModelMerge": "Alariva\\ModelMerge\\Facades\\ModelMerge" 39 | } 40 | } 41 | }, 42 | "scripts": { 43 | "coverage-report": [ 44 | "php -d xdebug.profiler_enable=On vendor/bin/phpunit --coverage-html tests/_report/" 45 | ] 46 | } 47 | } -------------------------------------------------------------------------------- /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": "e2492d8ac28ffee1e6ef3f04c9ab148d", 8 | "packages": [ 9 | { 10 | "name": "doctrine/inflector", 11 | "version": "v1.1.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/doctrine/inflector.git", 15 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", 20 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=5.3.2" 25 | }, 26 | "require-dev": { 27 | "phpunit/phpunit": "4.*" 28 | }, 29 | "type": "library", 30 | "extra": { 31 | "branch-alias": { 32 | "dev-master": "1.1.x-dev" 33 | } 34 | }, 35 | "autoload": { 36 | "psr-0": { 37 | "Doctrine\\Common\\Inflector\\": "lib/" 38 | } 39 | }, 40 | "notification-url": "https://packagist.org/downloads/", 41 | "license": [ 42 | "MIT" 43 | ], 44 | "authors": [ 45 | { 46 | "name": "Roman Borschel", 47 | "email": "roman@code-factory.org" 48 | }, 49 | { 50 | "name": "Benjamin Eberlei", 51 | "email": "kontakt@beberlei.de" 52 | }, 53 | { 54 | "name": "Guilherme Blanco", 55 | "email": "guilhermeblanco@gmail.com" 56 | }, 57 | { 58 | "name": "Jonathan Wage", 59 | "email": "jonwage@gmail.com" 60 | }, 61 | { 62 | "name": "Johannes Schmitt", 63 | "email": "schmittjoh@gmail.com" 64 | } 65 | ], 66 | "description": "Common String Manipulations with regard to casing and singular/plural rules.", 67 | "homepage": "http://www.doctrine-project.org", 68 | "keywords": [ 69 | "inflection", 70 | "pluralize", 71 | "singularize", 72 | "string" 73 | ], 74 | "time": "2015-11-06T14:35:42+00:00" 75 | }, 76 | { 77 | "name": "doctrine/lexer", 78 | "version": "v1.0.1", 79 | "source": { 80 | "type": "git", 81 | "url": "https://github.com/doctrine/lexer.git", 82 | "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" 83 | }, 84 | "dist": { 85 | "type": "zip", 86 | "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", 87 | "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", 88 | "shasum": "" 89 | }, 90 | "require": { 91 | "php": ">=5.3.2" 92 | }, 93 | "type": "library", 94 | "extra": { 95 | "branch-alias": { 96 | "dev-master": "1.0.x-dev" 97 | } 98 | }, 99 | "autoload": { 100 | "psr-0": { 101 | "Doctrine\\Common\\Lexer\\": "lib/" 102 | } 103 | }, 104 | "notification-url": "https://packagist.org/downloads/", 105 | "license": [ 106 | "MIT" 107 | ], 108 | "authors": [ 109 | { 110 | "name": "Roman Borschel", 111 | "email": "roman@code-factory.org" 112 | }, 113 | { 114 | "name": "Guilherme Blanco", 115 | "email": "guilhermeblanco@gmail.com" 116 | }, 117 | { 118 | "name": "Johannes Schmitt", 119 | "email": "schmittjoh@gmail.com" 120 | } 121 | ], 122 | "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", 123 | "homepage": "http://www.doctrine-project.org", 124 | "keywords": [ 125 | "lexer", 126 | "parser" 127 | ], 128 | "time": "2014-09-09T13:34:57+00:00" 129 | }, 130 | { 131 | "name": "egulias/email-validator", 132 | "version": "2.0.0", 133 | "source": { 134 | "type": "git", 135 | "url": "https://github.com/egulias/EmailValidator.git", 136 | "reference": "f5ea1fbb9c462f009994d6fcd3c0dd5eda719432" 137 | }, 138 | "dist": { 139 | "type": "zip", 140 | "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/f5ea1fbb9c462f009994d6fcd3c0dd5eda719432", 141 | "reference": "f5ea1fbb9c462f009994d6fcd3c0dd5eda719432", 142 | "shasum": "" 143 | }, 144 | "require": { 145 | "doctrine/lexer": "^1.0.1", 146 | "php": ">= 5.5" 147 | }, 148 | "require-dev": { 149 | "dominicsayers/isemail": "dev-master", 150 | "phpunit/phpunit": "^4.8.0", 151 | "satooshi/php-coveralls": "dev-master" 152 | }, 153 | "type": "library", 154 | "extra": { 155 | "branch-alias": { 156 | "dev-master": "2.0.x-dev" 157 | } 158 | }, 159 | "autoload": { 160 | "psr-4": { 161 | "Egulias\\EmailValidator\\": "EmailValidator" 162 | } 163 | }, 164 | "notification-url": "https://packagist.org/downloads/", 165 | "license": [ 166 | "MIT" 167 | ], 168 | "authors": [ 169 | { 170 | "name": "Eduardo Gulias Davis" 171 | } 172 | ], 173 | "description": "A library for validating emails against several RFCs", 174 | "homepage": "https://github.com/egulias/EmailValidator", 175 | "keywords": [ 176 | "email", 177 | "emailvalidation", 178 | "emailvalidator", 179 | "validation", 180 | "validator" 181 | ], 182 | "time": "2016-05-16T17:21:35+00:00" 183 | }, 184 | { 185 | "name": "erusev/parsedown", 186 | "version": "1.6.0", 187 | "source": { 188 | "type": "git", 189 | "url": "https://github.com/erusev/parsedown.git", 190 | "reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7" 191 | }, 192 | "dist": { 193 | "type": "zip", 194 | "url": "https://api.github.com/repos/erusev/parsedown/zipball/3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7", 195 | "reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7", 196 | "shasum": "" 197 | }, 198 | "type": "library", 199 | "autoload": { 200 | "psr-0": { 201 | "Parsedown": "" 202 | } 203 | }, 204 | "notification-url": "https://packagist.org/downloads/", 205 | "license": [ 206 | "MIT" 207 | ], 208 | "authors": [ 209 | { 210 | "name": "Emanuil Rusev", 211 | "email": "hello@erusev.com", 212 | "homepage": "http://erusev.com" 213 | } 214 | ], 215 | "description": "Parser for Markdown.", 216 | "homepage": "http://parsedown.org", 217 | "keywords": [ 218 | "markdown", 219 | "parser" 220 | ], 221 | "time": "2015-10-04T16:44:32+00:00" 222 | }, 223 | { 224 | "name": "laravel/framework", 225 | "version": "v5.5.0", 226 | "source": { 227 | "type": "git", 228 | "url": "https://github.com/laravel/framework.git", 229 | "reference": "bd352a0d2ca93775fce8ef02365b03fc4fb8cbb0" 230 | }, 231 | "dist": { 232 | "type": "zip", 233 | "url": "https://api.github.com/repos/laravel/framework/zipball/bd352a0d2ca93775fce8ef02365b03fc4fb8cbb0", 234 | "reference": "bd352a0d2ca93775fce8ef02365b03fc4fb8cbb0", 235 | "shasum": "" 236 | }, 237 | "require": { 238 | "doctrine/inflector": "~1.1", 239 | "erusev/parsedown": "~1.6", 240 | "ext-mbstring": "*", 241 | "ext-openssl": "*", 242 | "league/flysystem": "~1.0", 243 | "monolog/monolog": "~1.12", 244 | "mtdowling/cron-expression": "~1.0", 245 | "nesbot/carbon": "~1.20", 246 | "php": ">=7.0", 247 | "psr/container": "~1.0", 248 | "psr/simple-cache": "^1.0", 249 | "ramsey/uuid": "~3.0", 250 | "swiftmailer/swiftmailer": "~6.0", 251 | "symfony/console": "~3.3", 252 | "symfony/debug": "~3.3", 253 | "symfony/finder": "~3.3", 254 | "symfony/http-foundation": "~3.3", 255 | "symfony/http-kernel": "~3.3", 256 | "symfony/process": "~3.3", 257 | "symfony/routing": "~3.3", 258 | "symfony/var-dumper": "~3.3", 259 | "tijsverkoyen/css-to-inline-styles": "~2.2", 260 | "vlucas/phpdotenv": "~2.2" 261 | }, 262 | "replace": { 263 | "illuminate/auth": "self.version", 264 | "illuminate/broadcasting": "self.version", 265 | "illuminate/bus": "self.version", 266 | "illuminate/cache": "self.version", 267 | "illuminate/config": "self.version", 268 | "illuminate/console": "self.version", 269 | "illuminate/container": "self.version", 270 | "illuminate/contracts": "self.version", 271 | "illuminate/cookie": "self.version", 272 | "illuminate/database": "self.version", 273 | "illuminate/encryption": "self.version", 274 | "illuminate/events": "self.version", 275 | "illuminate/exception": "self.version", 276 | "illuminate/filesystem": "self.version", 277 | "illuminate/hashing": "self.version", 278 | "illuminate/http": "self.version", 279 | "illuminate/log": "self.version", 280 | "illuminate/mail": "self.version", 281 | "illuminate/notifications": "self.version", 282 | "illuminate/pagination": "self.version", 283 | "illuminate/pipeline": "self.version", 284 | "illuminate/queue": "self.version", 285 | "illuminate/redis": "self.version", 286 | "illuminate/routing": "self.version", 287 | "illuminate/session": "self.version", 288 | "illuminate/support": "self.version", 289 | "illuminate/translation": "self.version", 290 | "illuminate/validation": "self.version", 291 | "illuminate/view": "self.version", 292 | "tightenco/collect": "self.version" 293 | }, 294 | "require-dev": { 295 | "aws/aws-sdk-php": "~3.0", 296 | "doctrine/dbal": "~2.5", 297 | "filp/whoops": "^2.1.4", 298 | "mockery/mockery": "~0.9.4", 299 | "orchestra/testbench-core": "3.5.*", 300 | "pda/pheanstalk": "~3.0", 301 | "phpunit/phpunit": "~6.0", 302 | "predis/predis": "^1.1.1", 303 | "symfony/css-selector": "~3.3", 304 | "symfony/dom-crawler": "~3.3" 305 | }, 306 | "suggest": { 307 | "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).", 308 | "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.5).", 309 | "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", 310 | "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~6.0).", 311 | "laravel/tinker": "Required to use the tinker console command (~1.0).", 312 | "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", 313 | "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).", 314 | "nexmo/client": "Required to use the Nexmo transport (~1.0).", 315 | "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).", 316 | "predis/predis": "Required to use the redis cache and queue drivers (~1.0).", 317 | "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0).", 318 | "symfony/css-selector": "Required to use some of the crawler integration testing tools (~3.3).", 319 | "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (~3.3).", 320 | "symfony/psr-http-message-bridge": "Required to psr7 bridging features (0.2.*)." 321 | }, 322 | "type": "library", 323 | "extra": { 324 | "branch-alias": { 325 | "dev-master": "5.5-dev" 326 | } 327 | }, 328 | "autoload": { 329 | "files": [ 330 | "src/Illuminate/Foundation/helpers.php", 331 | "src/Illuminate/Support/helpers.php" 332 | ], 333 | "psr-4": { 334 | "Illuminate\\": "src/Illuminate/" 335 | } 336 | }, 337 | "notification-url": "https://packagist.org/downloads/", 338 | "license": [ 339 | "MIT" 340 | ], 341 | "authors": [ 342 | { 343 | "name": "Taylor Otwell", 344 | "email": "taylor@laravel.com" 345 | } 346 | ], 347 | "description": "The Laravel Framework.", 348 | "homepage": "https://laravel.com", 349 | "keywords": [ 350 | "framework", 351 | "laravel" 352 | ], 353 | "time": "2017-08-30T09:25:30+00:00" 354 | }, 355 | { 356 | "name": "league/flysystem", 357 | "version": "1.0.0", 358 | "source": { 359 | "type": "git", 360 | "url": "https://github.com/thephpleague/flysystem.git", 361 | "reference": "0ba6b6dfd6f456905ee8d6b0bcaab7ec89419b93" 362 | }, 363 | "dist": { 364 | "type": "zip", 365 | "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/0ba6b6dfd6f456905ee8d6b0bcaab7ec89419b93", 366 | "reference": "0ba6b6dfd6f456905ee8d6b0bcaab7ec89419b93", 367 | "shasum": "" 368 | }, 369 | "require": { 370 | "php": ">=5.4.0" 371 | }, 372 | "require-dev": { 373 | "ext-fileinfo": "*", 374 | "league/phpunit-coverage-listener": "~1.1", 375 | "mockery/mockery": "~0.9", 376 | "phpspec/phpspec": "~2.0.0", 377 | "phpspec/prophecy-phpunit": "~1.0", 378 | "phpunit/phpunit": "~4.0", 379 | "predis/predis": "~1.0", 380 | "tedivm/stash": "~0.12.0" 381 | }, 382 | "suggest": { 383 | "ext-fileinfo": "Required for MimeType", 384 | "league/flysystem-aws-s3-v2": "Use S3 storage with AWS SDK v2", 385 | "league/flysystem-aws-s3-v3": "Use S3 storage with AWS SDK v3", 386 | "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", 387 | "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", 388 | "league/flysystem-copy": "Allows you to use Copy.com storage", 389 | "league/flysystem-dropbox": "Use Dropbox storage", 390 | "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", 391 | "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", 392 | "league/flysystem-sftp": "Allows SFTP server storage via phpseclib", 393 | "league/flysystem-webdav": "Allows you to use WebDAV storage", 394 | "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", 395 | "predis/predis": "Allows you to use Predis for caching" 396 | }, 397 | "type": "library", 398 | "extra": { 399 | "branch-alias": { 400 | "dev-master": "1.0-dev" 401 | } 402 | }, 403 | "autoload": { 404 | "psr-4": { 405 | "League\\Flysystem\\": "src/" 406 | } 407 | }, 408 | "notification-url": "https://packagist.org/downloads/", 409 | "license": [ 410 | "MIT" 411 | ], 412 | "authors": [ 413 | { 414 | "name": "Frank de Jonge", 415 | "email": "info@frenky.net" 416 | } 417 | ], 418 | "description": "Many filesystems, one API.", 419 | "keywords": [ 420 | "Cloud Files", 421 | "WebDAV", 422 | "aws", 423 | "cloud", 424 | "copy.com", 425 | "dropbox", 426 | "file systems", 427 | "files", 428 | "filesystem", 429 | "ftp", 430 | "rackspace", 431 | "remote", 432 | "s3", 433 | "sftp", 434 | "storage" 435 | ], 436 | "time": "2015-01-19T19:19:07+00:00" 437 | }, 438 | { 439 | "name": "monolog/monolog", 440 | "version": "1.12.0", 441 | "source": { 442 | "type": "git", 443 | "url": "https://github.com/Seldaek/monolog.git", 444 | "reference": "1fbe8c2641f2b163addf49cc5e18f144bec6b19f" 445 | }, 446 | "dist": { 447 | "type": "zip", 448 | "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1fbe8c2641f2b163addf49cc5e18f144bec6b19f", 449 | "reference": "1fbe8c2641f2b163addf49cc5e18f144bec6b19f", 450 | "shasum": "" 451 | }, 452 | "require": { 453 | "php": ">=5.3.0", 454 | "psr/log": "~1.0" 455 | }, 456 | "provide": { 457 | "psr/log-implementation": "1.0.0" 458 | }, 459 | "require-dev": { 460 | "aws/aws-sdk-php": "~2.4, >2.4.8", 461 | "doctrine/couchdb": "~1.0@dev", 462 | "graylog2/gelf-php": "~1.0", 463 | "phpunit/phpunit": "~4.0", 464 | "raven/raven": "~0.5", 465 | "ruflin/elastica": "0.90.*", 466 | "videlalvaro/php-amqplib": "~2.4" 467 | }, 468 | "suggest": { 469 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", 470 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server", 471 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", 472 | "ext-mongo": "Allow sending log messages to a MongoDB server", 473 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", 474 | "raven/raven": "Allow sending log messages to a Sentry server", 475 | "rollbar/rollbar": "Allow sending log messages to Rollbar", 476 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server", 477 | "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib" 478 | }, 479 | "type": "library", 480 | "extra": { 481 | "branch-alias": { 482 | "dev-master": "1.12.x-dev" 483 | } 484 | }, 485 | "autoload": { 486 | "psr-4": { 487 | "Monolog\\": "src/Monolog" 488 | } 489 | }, 490 | "notification-url": "https://packagist.org/downloads/", 491 | "license": [ 492 | "MIT" 493 | ], 494 | "authors": [ 495 | { 496 | "name": "Jordi Boggiano", 497 | "email": "j.boggiano@seld.be", 498 | "homepage": "http://seld.be" 499 | } 500 | ], 501 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services", 502 | "homepage": "http://github.com/Seldaek/monolog", 503 | "keywords": [ 504 | "log", 505 | "logging", 506 | "psr-3" 507 | ], 508 | "time": "2014-12-29T21:29:35+00:00" 509 | }, 510 | { 511 | "name": "mtdowling/cron-expression", 512 | "version": "v1.0.0", 513 | "source": { 514 | "type": "git", 515 | "url": "https://github.com/mtdowling/cron-expression.git", 516 | "reference": "5a027522ef35bdc6996144fb9123472a5746bc02" 517 | }, 518 | "dist": { 519 | "type": "zip", 520 | "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/5a027522ef35bdc6996144fb9123472a5746bc02", 521 | "reference": "5a027522ef35bdc6996144fb9123472a5746bc02", 522 | "shasum": "" 523 | }, 524 | "require": { 525 | "php": ">=5.3.2" 526 | }, 527 | "type": "library", 528 | "autoload": { 529 | "psr-0": { 530 | "Cron": "src/" 531 | } 532 | }, 533 | "notification-url": "https://packagist.org/downloads/", 534 | "license": [ 535 | "MIT" 536 | ], 537 | "authors": [ 538 | { 539 | "name": "Michael Dowling", 540 | "email": "mtdowling@gmail.com", 541 | "homepage": "https://github.com/mtdowling" 542 | } 543 | ], 544 | "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", 545 | "keywords": [ 546 | "cron", 547 | "schedule" 548 | ], 549 | "time": "2012-07-15T21:19:48+00:00" 550 | }, 551 | { 552 | "name": "nesbot/carbon", 553 | "version": "1.20.0", 554 | "source": { 555 | "type": "git", 556 | "url": "https://github.com/briannesbitt/Carbon.git", 557 | "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3" 558 | }, 559 | "dist": { 560 | "type": "zip", 561 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bfd3eaba109c9a2405c92174c8e17f20c2b9caf3", 562 | "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3", 563 | "shasum": "" 564 | }, 565 | "require": { 566 | "php": ">=5.3.0", 567 | "symfony/translation": "~2.6|~3.0" 568 | }, 569 | "require-dev": { 570 | "phpunit/phpunit": "~4.0" 571 | }, 572 | "type": "library", 573 | "autoload": { 574 | "psr-0": { 575 | "Carbon": "src" 576 | } 577 | }, 578 | "notification-url": "https://packagist.org/downloads/", 579 | "license": [ 580 | "MIT" 581 | ], 582 | "authors": [ 583 | { 584 | "name": "Brian Nesbitt", 585 | "email": "brian@nesbot.com", 586 | "homepage": "http://nesbot.com" 587 | } 588 | ], 589 | "description": "A simple API extension for DateTime.", 590 | "homepage": "http://carbon.nesbot.com", 591 | "keywords": [ 592 | "date", 593 | "datetime", 594 | "time" 595 | ], 596 | "time": "2015-06-25T04:19:39+00:00" 597 | }, 598 | { 599 | "name": "psr/container", 600 | "version": "1.0.0", 601 | "source": { 602 | "type": "git", 603 | "url": "https://github.com/php-fig/container.git", 604 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" 605 | }, 606 | "dist": { 607 | "type": "zip", 608 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 609 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 610 | "shasum": "" 611 | }, 612 | "require": { 613 | "php": ">=5.3.0" 614 | }, 615 | "type": "library", 616 | "extra": { 617 | "branch-alias": { 618 | "dev-master": "1.0.x-dev" 619 | } 620 | }, 621 | "autoload": { 622 | "psr-4": { 623 | "Psr\\Container\\": "src/" 624 | } 625 | }, 626 | "notification-url": "https://packagist.org/downloads/", 627 | "license": [ 628 | "MIT" 629 | ], 630 | "authors": [ 631 | { 632 | "name": "PHP-FIG", 633 | "homepage": "http://www.php-fig.org/" 634 | } 635 | ], 636 | "description": "Common Container Interface (PHP FIG PSR-11)", 637 | "homepage": "https://github.com/php-fig/container", 638 | "keywords": [ 639 | "PSR-11", 640 | "container", 641 | "container-interface", 642 | "container-interop", 643 | "psr" 644 | ], 645 | "time": "2017-02-14T16:28:37+00:00" 646 | }, 647 | { 648 | "name": "psr/log", 649 | "version": "1.0.0", 650 | "source": { 651 | "type": "git", 652 | "url": "https://github.com/php-fig/log.git", 653 | "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" 654 | }, 655 | "dist": { 656 | "type": "zip", 657 | "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", 658 | "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", 659 | "shasum": "" 660 | }, 661 | "type": "library", 662 | "autoload": { 663 | "psr-0": { 664 | "Psr\\Log\\": "" 665 | } 666 | }, 667 | "notification-url": "https://packagist.org/downloads/", 668 | "license": [ 669 | "MIT" 670 | ], 671 | "authors": [ 672 | { 673 | "name": "PHP-FIG", 674 | "homepage": "http://www.php-fig.org/" 675 | } 676 | ], 677 | "description": "Common interface for logging libraries", 678 | "keywords": [ 679 | "log", 680 | "psr", 681 | "psr-3" 682 | ], 683 | "time": "2012-12-21T11:40:51+00:00" 684 | }, 685 | { 686 | "name": "psr/simple-cache", 687 | "version": "1.0.0", 688 | "source": { 689 | "type": "git", 690 | "url": "https://github.com/php-fig/simple-cache.git", 691 | "reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24" 692 | }, 693 | "dist": { 694 | "type": "zip", 695 | "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/753fa598e8f3b9966c886fe13f370baa45ef0e24", 696 | "reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24", 697 | "shasum": "" 698 | }, 699 | "require": { 700 | "php": ">=5.3.0" 701 | }, 702 | "type": "library", 703 | "extra": { 704 | "branch-alias": { 705 | "dev-master": "1.0.x-dev" 706 | } 707 | }, 708 | "autoload": { 709 | "psr-4": { 710 | "Psr\\SimpleCache\\": "src/" 711 | } 712 | }, 713 | "notification-url": "https://packagist.org/downloads/", 714 | "license": [ 715 | "MIT" 716 | ], 717 | "authors": [ 718 | { 719 | "name": "PHP-FIG", 720 | "homepage": "http://www.php-fig.org/" 721 | } 722 | ], 723 | "description": "Common interfaces for simple caching", 724 | "keywords": [ 725 | "cache", 726 | "caching", 727 | "psr", 728 | "psr-16", 729 | "simple-cache" 730 | ], 731 | "time": "2017-01-02T13:31:39+00:00" 732 | }, 733 | { 734 | "name": "ramsey/uuid", 735 | "version": "3.0.0", 736 | "source": { 737 | "type": "git", 738 | "url": "https://github.com/ramsey/uuid.git", 739 | "reference": "0c0ac34e867219bb9936cc5b823f8a5af840d7eb" 740 | }, 741 | "dist": { 742 | "type": "zip", 743 | "url": "https://api.github.com/repos/ramsey/uuid/zipball/0c0ac34e867219bb9936cc5b823f8a5af840d7eb", 744 | "reference": "0c0ac34e867219bb9936cc5b823f8a5af840d7eb", 745 | "shasum": "" 746 | }, 747 | "require": { 748 | "php": ">=5.4" 749 | }, 750 | "replace": { 751 | "rhumsaa/uuid": "self.version" 752 | }, 753 | "require-dev": { 754 | "apigen/apigen": "^4.1", 755 | "ircmaxell/random-lib": "^1.1", 756 | "jakub-onderka/php-parallel-lint": "^0.9.0", 757 | "moontoast/math": "^1.1", 758 | "phpunit/phpunit": "^4.7", 759 | "satooshi/php-coveralls": "^0.6.1", 760 | "squizlabs/php_codesniffer": "^2.3" 761 | }, 762 | "suggest": { 763 | "ircmaxell/random-lib": "Provides RandomLib to use with the RandomLibAdapter", 764 | "moontoast/math": "Support for converting UUID to 128-bit integer (in string form).", 765 | "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", 766 | "ramsey/uuid-doctrine": "Allow the use of a UUID as Doctrine field type." 767 | }, 768 | "type": "library", 769 | "extra": { 770 | "branch-alias": { 771 | "dev-master": "3.0.x-dev" 772 | } 773 | }, 774 | "autoload": { 775 | "psr-4": { 776 | "Ramsey\\Uuid\\": "src/" 777 | } 778 | }, 779 | "notification-url": "https://packagist.org/downloads/", 780 | "license": [ 781 | "MIT" 782 | ], 783 | "authors": [ 784 | { 785 | "name": "Marijn Huizendveld", 786 | "email": "marijn.huizendveld@gmail.com" 787 | }, 788 | { 789 | "name": "Thibaud Fabre", 790 | "email": "thibaud@aztech.io" 791 | }, 792 | { 793 | "name": "Ben Ramsey", 794 | "email": "ben@benramsey.com", 795 | "homepage": "https://benramsey.com" 796 | } 797 | ], 798 | "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", 799 | "homepage": "https://github.com/ramsey/uuid", 800 | "keywords": [ 801 | "guid", 802 | "identifier", 803 | "uuid" 804 | ], 805 | "time": "2015-09-28T16:27:51+00:00" 806 | }, 807 | { 808 | "name": "swiftmailer/swiftmailer", 809 | "version": "v6.0.0", 810 | "source": { 811 | "type": "git", 812 | "url": "https://github.com/swiftmailer/swiftmailer.git", 813 | "reference": "74e20ce4dad5011fb2c2cedefb76b2237f123c0e" 814 | }, 815 | "dist": { 816 | "type": "zip", 817 | "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/74e20ce4dad5011fb2c2cedefb76b2237f123c0e", 818 | "reference": "74e20ce4dad5011fb2c2cedefb76b2237f123c0e", 819 | "shasum": "" 820 | }, 821 | "require": { 822 | "egulias/email-validator": "~2.0", 823 | "php": ">=7.0.0" 824 | }, 825 | "require-dev": { 826 | "mockery/mockery": "~0.9.1", 827 | "symfony/phpunit-bridge": "~3.3@dev" 828 | }, 829 | "type": "library", 830 | "extra": { 831 | "branch-alias": { 832 | "dev-master": "6.0-dev" 833 | } 834 | }, 835 | "autoload": { 836 | "files": [ 837 | "lib/swift_required.php" 838 | ] 839 | }, 840 | "notification-url": "https://packagist.org/downloads/", 841 | "license": [ 842 | "MIT" 843 | ], 844 | "authors": [ 845 | { 846 | "name": "Chris Corbyn" 847 | }, 848 | { 849 | "name": "Fabien Potencier", 850 | "email": "fabien@symfony.com" 851 | } 852 | ], 853 | "description": "Swiftmailer, free feature-rich PHP mailer", 854 | "homepage": "http://swiftmailer.org", 855 | "keywords": [ 856 | "email", 857 | "mail", 858 | "mailer" 859 | ], 860 | "time": "2017-05-19T19:50:13+00:00" 861 | }, 862 | { 863 | "name": "symfony/console", 864 | "version": "v3.3.0", 865 | "source": { 866 | "type": "git", 867 | "url": "https://github.com/symfony/console.git", 868 | "reference": "c80e63f3f5e3a331bfc25e6e9332b10422eb9b05" 869 | }, 870 | "dist": { 871 | "type": "zip", 872 | "url": "https://api.github.com/repos/symfony/console/zipball/c80e63f3f5e3a331bfc25e6e9332b10422eb9b05", 873 | "reference": "c80e63f3f5e3a331bfc25e6e9332b10422eb9b05", 874 | "shasum": "" 875 | }, 876 | "require": { 877 | "php": ">=5.5.9", 878 | "symfony/debug": "~2.8|~3.0", 879 | "symfony/polyfill-mbstring": "~1.0" 880 | }, 881 | "conflict": { 882 | "symfony/dependency-injection": "<3.3" 883 | }, 884 | "require-dev": { 885 | "psr/log": "~1.0", 886 | "symfony/dependency-injection": "~3.3", 887 | "symfony/event-dispatcher": "~2.8|~3.0", 888 | "symfony/filesystem": "~2.8|~3.0", 889 | "symfony/http-kernel": "~2.8|~3.0", 890 | "symfony/process": "~2.8|~3.0" 891 | }, 892 | "suggest": { 893 | "psr/log": "For using the console logger", 894 | "symfony/event-dispatcher": "", 895 | "symfony/filesystem": "", 896 | "symfony/process": "" 897 | }, 898 | "type": "library", 899 | "extra": { 900 | "branch-alias": { 901 | "dev-master": "3.3-dev" 902 | } 903 | }, 904 | "autoload": { 905 | "psr-4": { 906 | "Symfony\\Component\\Console\\": "" 907 | }, 908 | "exclude-from-classmap": [ 909 | "/Tests/" 910 | ] 911 | }, 912 | "notification-url": "https://packagist.org/downloads/", 913 | "license": [ 914 | "MIT" 915 | ], 916 | "authors": [ 917 | { 918 | "name": "Fabien Potencier", 919 | "email": "fabien@symfony.com" 920 | }, 921 | { 922 | "name": "Symfony Community", 923 | "homepage": "https://symfony.com/contributors" 924 | } 925 | ], 926 | "description": "Symfony Console Component", 927 | "homepage": "https://symfony.com", 928 | "time": "2017-05-28T14:08:56+00:00" 929 | }, 930 | { 931 | "name": "symfony/css-selector", 932 | "version": "v2.7.0", 933 | "source": { 934 | "type": "git", 935 | "url": "https://github.com/symfony/css-selector.git", 936 | "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092" 937 | }, 938 | "dist": { 939 | "type": "zip", 940 | "url": "https://api.github.com/repos/symfony/css-selector/zipball/0b5c07b516226b7dd32afbbc82fe547a469c5092", 941 | "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092", 942 | "shasum": "" 943 | }, 944 | "require": { 945 | "php": ">=5.3.9" 946 | }, 947 | "require-dev": { 948 | "symfony/phpunit-bridge": "~2.7" 949 | }, 950 | "type": "library", 951 | "extra": { 952 | "branch-alias": { 953 | "dev-master": "2.7-dev" 954 | } 955 | }, 956 | "autoload": { 957 | "psr-4": { 958 | "Symfony\\Component\\CssSelector\\": "" 959 | } 960 | }, 961 | "notification-url": "https://packagist.org/downloads/", 962 | "license": [ 963 | "MIT" 964 | ], 965 | "authors": [ 966 | { 967 | "name": "Jean-François Simon", 968 | "email": "jeanfrancois.simon@sensiolabs.com" 969 | }, 970 | { 971 | "name": "Fabien Potencier", 972 | "email": "fabien@symfony.com" 973 | }, 974 | { 975 | "name": "Symfony Community", 976 | "homepage": "https://symfony.com/contributors" 977 | } 978 | ], 979 | "description": "Symfony CssSelector Component", 980 | "homepage": "https://symfony.com", 981 | "time": "2015-05-15T13:33:16+00:00" 982 | }, 983 | { 984 | "name": "symfony/debug", 985 | "version": "v3.3.0", 986 | "source": { 987 | "type": "git", 988 | "url": "https://github.com/symfony/debug.git", 989 | "reference": "ef5f19a7a68075a0bd05969a329ead3b0776fb7a" 990 | }, 991 | "dist": { 992 | "type": "zip", 993 | "url": "https://api.github.com/repos/symfony/debug/zipball/ef5f19a7a68075a0bd05969a329ead3b0776fb7a", 994 | "reference": "ef5f19a7a68075a0bd05969a329ead3b0776fb7a", 995 | "shasum": "" 996 | }, 997 | "require": { 998 | "php": ">=5.5.9", 999 | "psr/log": "~1.0" 1000 | }, 1001 | "conflict": { 1002 | "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" 1003 | }, 1004 | "require-dev": { 1005 | "symfony/http-kernel": "~2.8|~3.0" 1006 | }, 1007 | "type": "library", 1008 | "extra": { 1009 | "branch-alias": { 1010 | "dev-master": "3.3-dev" 1011 | } 1012 | }, 1013 | "autoload": { 1014 | "psr-4": { 1015 | "Symfony\\Component\\Debug\\": "" 1016 | }, 1017 | "exclude-from-classmap": [ 1018 | "/Tests/" 1019 | ] 1020 | }, 1021 | "notification-url": "https://packagist.org/downloads/", 1022 | "license": [ 1023 | "MIT" 1024 | ], 1025 | "authors": [ 1026 | { 1027 | "name": "Fabien Potencier", 1028 | "email": "fabien@symfony.com" 1029 | }, 1030 | { 1031 | "name": "Symfony Community", 1032 | "homepage": "https://symfony.com/contributors" 1033 | } 1034 | ], 1035 | "description": "Symfony Debug Component", 1036 | "homepage": "https://symfony.com", 1037 | "time": "2017-05-27T16:02:27+00:00" 1038 | }, 1039 | { 1040 | "name": "symfony/event-dispatcher", 1041 | "version": "v2.8.0", 1042 | "source": { 1043 | "type": "git", 1044 | "url": "https://github.com/symfony/event-dispatcher.git", 1045 | "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc" 1046 | }, 1047 | "dist": { 1048 | "type": "zip", 1049 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc", 1050 | "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc", 1051 | "shasum": "" 1052 | }, 1053 | "require": { 1054 | "php": ">=5.3.9" 1055 | }, 1056 | "require-dev": { 1057 | "psr/log": "~1.0", 1058 | "symfony/config": "~2.0,>=2.0.5|~3.0.0", 1059 | "symfony/dependency-injection": "~2.6|~3.0.0", 1060 | "symfony/expression-language": "~2.6|~3.0.0", 1061 | "symfony/stopwatch": "~2.3|~3.0.0" 1062 | }, 1063 | "suggest": { 1064 | "symfony/dependency-injection": "", 1065 | "symfony/http-kernel": "" 1066 | }, 1067 | "type": "library", 1068 | "extra": { 1069 | "branch-alias": { 1070 | "dev-master": "2.8-dev" 1071 | } 1072 | }, 1073 | "autoload": { 1074 | "psr-4": { 1075 | "Symfony\\Component\\EventDispatcher\\": "" 1076 | }, 1077 | "exclude-from-classmap": [ 1078 | "/Tests/" 1079 | ] 1080 | }, 1081 | "notification-url": "https://packagist.org/downloads/", 1082 | "license": [ 1083 | "MIT" 1084 | ], 1085 | "authors": [ 1086 | { 1087 | "name": "Fabien Potencier", 1088 | "email": "fabien@symfony.com" 1089 | }, 1090 | { 1091 | "name": "Symfony Community", 1092 | "homepage": "https://symfony.com/contributors" 1093 | } 1094 | ], 1095 | "description": "Symfony EventDispatcher Component", 1096 | "homepage": "https://symfony.com", 1097 | "time": "2015-10-30T20:15:42+00:00" 1098 | }, 1099 | { 1100 | "name": "symfony/finder", 1101 | "version": "v3.3.0", 1102 | "source": { 1103 | "type": "git", 1104 | "url": "https://github.com/symfony/finder.git", 1105 | "reference": "30cb2a2c09627823a7243638dd456de4e2748fed" 1106 | }, 1107 | "dist": { 1108 | "type": "zip", 1109 | "url": "https://api.github.com/repos/symfony/finder/zipball/30cb2a2c09627823a7243638dd456de4e2748fed", 1110 | "reference": "30cb2a2c09627823a7243638dd456de4e2748fed", 1111 | "shasum": "" 1112 | }, 1113 | "require": { 1114 | "php": ">=5.5.9" 1115 | }, 1116 | "type": "library", 1117 | "extra": { 1118 | "branch-alias": { 1119 | "dev-master": "3.3-dev" 1120 | } 1121 | }, 1122 | "autoload": { 1123 | "psr-4": { 1124 | "Symfony\\Component\\Finder\\": "" 1125 | }, 1126 | "exclude-from-classmap": [ 1127 | "/Tests/" 1128 | ] 1129 | }, 1130 | "notification-url": "https://packagist.org/downloads/", 1131 | "license": [ 1132 | "MIT" 1133 | ], 1134 | "authors": [ 1135 | { 1136 | "name": "Fabien Potencier", 1137 | "email": "fabien@symfony.com" 1138 | }, 1139 | { 1140 | "name": "Symfony Community", 1141 | "homepage": "https://symfony.com/contributors" 1142 | } 1143 | ], 1144 | "description": "Symfony Finder Component", 1145 | "homepage": "https://symfony.com", 1146 | "time": "2017-05-25T23:10:31+00:00" 1147 | }, 1148 | { 1149 | "name": "symfony/http-foundation", 1150 | "version": "v3.3.0", 1151 | "source": { 1152 | "type": "git", 1153 | "url": "https://github.com/symfony/http-foundation.git", 1154 | "reference": "a3272c06d538bd48261e7d83308e7f84992d4ec8" 1155 | }, 1156 | "dist": { 1157 | "type": "zip", 1158 | "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a3272c06d538bd48261e7d83308e7f84992d4ec8", 1159 | "reference": "a3272c06d538bd48261e7d83308e7f84992d4ec8", 1160 | "shasum": "" 1161 | }, 1162 | "require": { 1163 | "php": ">=5.5.9", 1164 | "symfony/polyfill-mbstring": "~1.1" 1165 | }, 1166 | "require-dev": { 1167 | "symfony/expression-language": "~2.8|~3.0" 1168 | }, 1169 | "type": "library", 1170 | "extra": { 1171 | "branch-alias": { 1172 | "dev-master": "3.3-dev" 1173 | } 1174 | }, 1175 | "autoload": { 1176 | "psr-4": { 1177 | "Symfony\\Component\\HttpFoundation\\": "" 1178 | }, 1179 | "exclude-from-classmap": [ 1180 | "/Tests/" 1181 | ] 1182 | }, 1183 | "notification-url": "https://packagist.org/downloads/", 1184 | "license": [ 1185 | "MIT" 1186 | ], 1187 | "authors": [ 1188 | { 1189 | "name": "Fabien Potencier", 1190 | "email": "fabien@symfony.com" 1191 | }, 1192 | { 1193 | "name": "Symfony Community", 1194 | "homepage": "https://symfony.com/contributors" 1195 | } 1196 | ], 1197 | "description": "Symfony HttpFoundation Component", 1198 | "homepage": "https://symfony.com", 1199 | "time": "2017-05-25T13:39:26+00:00" 1200 | }, 1201 | { 1202 | "name": "symfony/http-kernel", 1203 | "version": "v3.3.0", 1204 | "source": { 1205 | "type": "git", 1206 | "url": "https://github.com/symfony/http-kernel.git", 1207 | "reference": "4ad34a0d20a5848c0fcbf6ff6a2ff1cd9cf4b9ed" 1208 | }, 1209 | "dist": { 1210 | "type": "zip", 1211 | "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4ad34a0d20a5848c0fcbf6ff6a2ff1cd9cf4b9ed", 1212 | "reference": "4ad34a0d20a5848c0fcbf6ff6a2ff1cd9cf4b9ed", 1213 | "shasum": "" 1214 | }, 1215 | "require": { 1216 | "php": ">=5.5.9", 1217 | "psr/log": "~1.0", 1218 | "symfony/debug": "~2.8|~3.0", 1219 | "symfony/event-dispatcher": "~2.8|~3.0", 1220 | "symfony/http-foundation": "~3.3" 1221 | }, 1222 | "conflict": { 1223 | "symfony/config": "<2.8", 1224 | "symfony/dependency-injection": "<3.3", 1225 | "symfony/var-dumper": "<3.3" 1226 | }, 1227 | "require-dev": { 1228 | "psr/cache": "~1.0", 1229 | "symfony/browser-kit": "~2.8|~3.0", 1230 | "symfony/class-loader": "~2.8|~3.0", 1231 | "symfony/config": "~2.8|~3.0", 1232 | "symfony/console": "~2.8|~3.0", 1233 | "symfony/css-selector": "~2.8|~3.0", 1234 | "symfony/dependency-injection": "~3.3", 1235 | "symfony/dom-crawler": "~2.8|~3.0", 1236 | "symfony/expression-language": "~2.8|~3.0", 1237 | "symfony/finder": "~2.8|~3.0", 1238 | "symfony/process": "~2.8|~3.0", 1239 | "symfony/routing": "~2.8|~3.0", 1240 | "symfony/stopwatch": "~2.8|~3.0", 1241 | "symfony/templating": "~2.8|~3.0", 1242 | "symfony/translation": "~2.8|~3.0", 1243 | "symfony/var-dumper": "~3.3" 1244 | }, 1245 | "suggest": { 1246 | "symfony/browser-kit": "", 1247 | "symfony/class-loader": "", 1248 | "symfony/config": "", 1249 | "symfony/console": "", 1250 | "symfony/dependency-injection": "", 1251 | "symfony/finder": "", 1252 | "symfony/var-dumper": "" 1253 | }, 1254 | "type": "library", 1255 | "extra": { 1256 | "branch-alias": { 1257 | "dev-master": "3.3-dev" 1258 | } 1259 | }, 1260 | "autoload": { 1261 | "psr-4": { 1262 | "Symfony\\Component\\HttpKernel\\": "" 1263 | }, 1264 | "exclude-from-classmap": [ 1265 | "/Tests/" 1266 | ] 1267 | }, 1268 | "notification-url": "https://packagist.org/downloads/", 1269 | "license": [ 1270 | "MIT" 1271 | ], 1272 | "authors": [ 1273 | { 1274 | "name": "Fabien Potencier", 1275 | "email": "fabien@symfony.com" 1276 | }, 1277 | { 1278 | "name": "Symfony Community", 1279 | "homepage": "https://symfony.com/contributors" 1280 | } 1281 | ], 1282 | "description": "Symfony HttpKernel Component", 1283 | "homepage": "https://symfony.com", 1284 | "time": "2017-05-29T21:02:12+00:00" 1285 | }, 1286 | { 1287 | "name": "symfony/polyfill-mbstring", 1288 | "version": "v1.1.0", 1289 | "source": { 1290 | "type": "git", 1291 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1292 | "reference": "1289d16209491b584839022f29257ad859b8532d" 1293 | }, 1294 | "dist": { 1295 | "type": "zip", 1296 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", 1297 | "reference": "1289d16209491b584839022f29257ad859b8532d", 1298 | "shasum": "" 1299 | }, 1300 | "require": { 1301 | "php": ">=5.3.3" 1302 | }, 1303 | "suggest": { 1304 | "ext-mbstring": "For best performance" 1305 | }, 1306 | "type": "library", 1307 | "extra": { 1308 | "branch-alias": { 1309 | "dev-master": "1.1-dev" 1310 | } 1311 | }, 1312 | "autoload": { 1313 | "psr-4": { 1314 | "Symfony\\Polyfill\\Mbstring\\": "" 1315 | }, 1316 | "files": [ 1317 | "bootstrap.php" 1318 | ] 1319 | }, 1320 | "notification-url": "https://packagist.org/downloads/", 1321 | "license": [ 1322 | "MIT" 1323 | ], 1324 | "authors": [ 1325 | { 1326 | "name": "Nicolas Grekas", 1327 | "email": "p@tchwork.com" 1328 | }, 1329 | { 1330 | "name": "Symfony Community", 1331 | "homepage": "https://symfony.com/contributors" 1332 | } 1333 | ], 1334 | "description": "Symfony polyfill for the Mbstring extension", 1335 | "homepage": "https://symfony.com", 1336 | "keywords": [ 1337 | "compatibility", 1338 | "mbstring", 1339 | "polyfill", 1340 | "portable", 1341 | "shim" 1342 | ], 1343 | "time": "2016-01-20T09:13:37+00:00" 1344 | }, 1345 | { 1346 | "name": "symfony/process", 1347 | "version": "v3.3.0", 1348 | "source": { 1349 | "type": "git", 1350 | "url": "https://github.com/symfony/process.git", 1351 | "reference": "8e30690c67aafb6c7992d6d8eb0d707807dd3eaf" 1352 | }, 1353 | "dist": { 1354 | "type": "zip", 1355 | "url": "https://api.github.com/repos/symfony/process/zipball/8e30690c67aafb6c7992d6d8eb0d707807dd3eaf", 1356 | "reference": "8e30690c67aafb6c7992d6d8eb0d707807dd3eaf", 1357 | "shasum": "" 1358 | }, 1359 | "require": { 1360 | "php": ">=5.5.9" 1361 | }, 1362 | "type": "library", 1363 | "extra": { 1364 | "branch-alias": { 1365 | "dev-master": "3.3-dev" 1366 | } 1367 | }, 1368 | "autoload": { 1369 | "psr-4": { 1370 | "Symfony\\Component\\Process\\": "" 1371 | }, 1372 | "exclude-from-classmap": [ 1373 | "/Tests/" 1374 | ] 1375 | }, 1376 | "notification-url": "https://packagist.org/downloads/", 1377 | "license": [ 1378 | "MIT" 1379 | ], 1380 | "authors": [ 1381 | { 1382 | "name": "Fabien Potencier", 1383 | "email": "fabien@symfony.com" 1384 | }, 1385 | { 1386 | "name": "Symfony Community", 1387 | "homepage": "https://symfony.com/contributors" 1388 | } 1389 | ], 1390 | "description": "Symfony Process Component", 1391 | "homepage": "https://symfony.com", 1392 | "time": "2017-05-22T12:32:03+00:00" 1393 | }, 1394 | { 1395 | "name": "symfony/routing", 1396 | "version": "v3.3.0", 1397 | "source": { 1398 | "type": "git", 1399 | "url": "https://github.com/symfony/routing.git", 1400 | "reference": "3aa0c7d759a2c88f4dff47c3d6776e7380bb2c9a" 1401 | }, 1402 | "dist": { 1403 | "type": "zip", 1404 | "url": "https://api.github.com/repos/symfony/routing/zipball/3aa0c7d759a2c88f4dff47c3d6776e7380bb2c9a", 1405 | "reference": "3aa0c7d759a2c88f4dff47c3d6776e7380bb2c9a", 1406 | "shasum": "" 1407 | }, 1408 | "require": { 1409 | "php": ">=5.5.9" 1410 | }, 1411 | "conflict": { 1412 | "symfony/config": "<2.8", 1413 | "symfony/dependency-injection": "<3.3", 1414 | "symfony/yaml": "<3.3" 1415 | }, 1416 | "require-dev": { 1417 | "doctrine/annotations": "~1.0", 1418 | "doctrine/common": "~2.2", 1419 | "psr/log": "~1.0", 1420 | "symfony/config": "~2.8|~3.0", 1421 | "symfony/dependency-injection": "~3.3", 1422 | "symfony/expression-language": "~2.8|~3.0", 1423 | "symfony/http-foundation": "~2.8|~3.0", 1424 | "symfony/yaml": "~3.3" 1425 | }, 1426 | "suggest": { 1427 | "doctrine/annotations": "For using the annotation loader", 1428 | "symfony/config": "For using the all-in-one router or any loader", 1429 | "symfony/dependency-injection": "For loading routes from a service", 1430 | "symfony/expression-language": "For using expression matching", 1431 | "symfony/http-foundation": "For using a Symfony Request object", 1432 | "symfony/yaml": "For using the YAML loader" 1433 | }, 1434 | "type": "library", 1435 | "extra": { 1436 | "branch-alias": { 1437 | "dev-master": "3.3-dev" 1438 | } 1439 | }, 1440 | "autoload": { 1441 | "psr-4": { 1442 | "Symfony\\Component\\Routing\\": "" 1443 | }, 1444 | "exclude-from-classmap": [ 1445 | "/Tests/" 1446 | ] 1447 | }, 1448 | "notification-url": "https://packagist.org/downloads/", 1449 | "license": [ 1450 | "MIT" 1451 | ], 1452 | "authors": [ 1453 | { 1454 | "name": "Fabien Potencier", 1455 | "email": "fabien@symfony.com" 1456 | }, 1457 | { 1458 | "name": "Symfony Community", 1459 | "homepage": "https://symfony.com/contributors" 1460 | } 1461 | ], 1462 | "description": "Symfony Routing Component", 1463 | "homepage": "https://symfony.com", 1464 | "keywords": [ 1465 | "router", 1466 | "routing", 1467 | "uri", 1468 | "url" 1469 | ], 1470 | "time": "2017-05-24T11:35:23+00:00" 1471 | }, 1472 | { 1473 | "name": "symfony/translation", 1474 | "version": "v2.6.0", 1475 | "target-dir": "Symfony/Component/Translation", 1476 | "source": { 1477 | "type": "git", 1478 | "url": "https://github.com/symfony/Translation.git", 1479 | "reference": "0a3711860976f15ee46642b4dd354e9ef9fc9a15" 1480 | }, 1481 | "dist": { 1482 | "type": "zip", 1483 | "url": "https://api.github.com/repos/symfony/Translation/zipball/0a3711860976f15ee46642b4dd354e9ef9fc9a15", 1484 | "reference": "0a3711860976f15ee46642b4dd354e9ef9fc9a15", 1485 | "shasum": "" 1486 | }, 1487 | "require": { 1488 | "php": ">=5.3.3" 1489 | }, 1490 | "require-dev": { 1491 | "psr/log": "~1.0", 1492 | "symfony/config": "~2.0", 1493 | "symfony/intl": "~2.3", 1494 | "symfony/yaml": "~2.2" 1495 | }, 1496 | "suggest": { 1497 | "psr/log": "To use logging capability in translator", 1498 | "symfony/config": "", 1499 | "symfony/yaml": "" 1500 | }, 1501 | "type": "library", 1502 | "extra": { 1503 | "branch-alias": { 1504 | "dev-master": "2.6-dev" 1505 | } 1506 | }, 1507 | "autoload": { 1508 | "psr-0": { 1509 | "Symfony\\Component\\Translation\\": "" 1510 | } 1511 | }, 1512 | "notification-url": "https://packagist.org/downloads/", 1513 | "license": [ 1514 | "MIT" 1515 | ], 1516 | "authors": [ 1517 | { 1518 | "name": "Symfony Community", 1519 | "homepage": "http://symfony.com/contributors" 1520 | }, 1521 | { 1522 | "name": "Fabien Potencier", 1523 | "email": "fabien@symfony.com" 1524 | } 1525 | ], 1526 | "description": "Symfony Translation Component", 1527 | "homepage": "http://symfony.com", 1528 | "time": "2014-11-28T10:00:40+00:00" 1529 | }, 1530 | { 1531 | "name": "symfony/var-dumper", 1532 | "version": "v3.3.0", 1533 | "source": { 1534 | "type": "git", 1535 | "url": "https://github.com/symfony/var-dumper.git", 1536 | "reference": "568ce40d88b14f6b42aa48f50572cc4427be9757" 1537 | }, 1538 | "dist": { 1539 | "type": "zip", 1540 | "url": "https://api.github.com/repos/symfony/var-dumper/zipball/568ce40d88b14f6b42aa48f50572cc4427be9757", 1541 | "reference": "568ce40d88b14f6b42aa48f50572cc4427be9757", 1542 | "shasum": "" 1543 | }, 1544 | "require": { 1545 | "php": ">=5.5.9", 1546 | "symfony/polyfill-mbstring": "~1.0" 1547 | }, 1548 | "conflict": { 1549 | "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" 1550 | }, 1551 | "require-dev": { 1552 | "ext-iconv": "*", 1553 | "twig/twig": "~1.20|~2.0" 1554 | }, 1555 | "suggest": { 1556 | "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", 1557 | "ext-symfony_debug": "" 1558 | }, 1559 | "type": "library", 1560 | "extra": { 1561 | "branch-alias": { 1562 | "dev-master": "3.3-dev" 1563 | } 1564 | }, 1565 | "autoload": { 1566 | "files": [ 1567 | "Resources/functions/dump.php" 1568 | ], 1569 | "psr-4": { 1570 | "Symfony\\Component\\VarDumper\\": "" 1571 | }, 1572 | "exclude-from-classmap": [ 1573 | "/Tests/" 1574 | ] 1575 | }, 1576 | "notification-url": "https://packagist.org/downloads/", 1577 | "license": [ 1578 | "MIT" 1579 | ], 1580 | "authors": [ 1581 | { 1582 | "name": "Nicolas Grekas", 1583 | "email": "p@tchwork.com" 1584 | }, 1585 | { 1586 | "name": "Symfony Community", 1587 | "homepage": "https://symfony.com/contributors" 1588 | } 1589 | ], 1590 | "description": "Symfony mechanism for exploring and dumping PHP variables", 1591 | "homepage": "https://symfony.com", 1592 | "keywords": [ 1593 | "debug", 1594 | "dump" 1595 | ], 1596 | "time": "2017-05-22T17:32:12+00:00" 1597 | }, 1598 | { 1599 | "name": "tijsverkoyen/css-to-inline-styles", 1600 | "version": "2.2.0", 1601 | "source": { 1602 | "type": "git", 1603 | "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", 1604 | "reference": "ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b" 1605 | }, 1606 | "dist": { 1607 | "type": "zip", 1608 | "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b", 1609 | "reference": "ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b", 1610 | "shasum": "" 1611 | }, 1612 | "require": { 1613 | "php": "^5.5 || ^7", 1614 | "symfony/css-selector": "^2.7|~3.0" 1615 | }, 1616 | "require-dev": { 1617 | "phpunit/phpunit": "~4.8|5.1.*" 1618 | }, 1619 | "type": "library", 1620 | "extra": { 1621 | "branch-alias": { 1622 | "dev-master": "2.0.x-dev" 1623 | } 1624 | }, 1625 | "autoload": { 1626 | "psr-4": { 1627 | "TijsVerkoyen\\CssToInlineStyles\\": "src" 1628 | } 1629 | }, 1630 | "notification-url": "https://packagist.org/downloads/", 1631 | "license": [ 1632 | "BSD-3-Clause" 1633 | ], 1634 | "authors": [ 1635 | { 1636 | "name": "Tijs Verkoyen", 1637 | "email": "css_to_inline_styles@verkoyen.eu", 1638 | "role": "Developer" 1639 | } 1640 | ], 1641 | "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", 1642 | "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", 1643 | "time": "2016-09-20T12:50:39+00:00" 1644 | }, 1645 | { 1646 | "name": "vlucas/phpdotenv", 1647 | "version": "v2.2.0", 1648 | "source": { 1649 | "type": "git", 1650 | "url": "https://github.com/vlucas/phpdotenv.git", 1651 | "reference": "9caf304153dc2288e4970caec6f1f3b3bc205412" 1652 | }, 1653 | "dist": { 1654 | "type": "zip", 1655 | "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/9caf304153dc2288e4970caec6f1f3b3bc205412", 1656 | "reference": "9caf304153dc2288e4970caec6f1f3b3bc205412", 1657 | "shasum": "" 1658 | }, 1659 | "require": { 1660 | "php": ">=5.3.9" 1661 | }, 1662 | "require-dev": { 1663 | "phpunit/phpunit": "^4.8|^5.0" 1664 | }, 1665 | "type": "library", 1666 | "extra": { 1667 | "branch-alias": { 1668 | "dev-master": "2.2-dev" 1669 | } 1670 | }, 1671 | "autoload": { 1672 | "psr-4": { 1673 | "Dotenv\\": "src/" 1674 | } 1675 | }, 1676 | "notification-url": "https://packagist.org/downloads/", 1677 | "license": [ 1678 | "BSD" 1679 | ], 1680 | "authors": [ 1681 | { 1682 | "name": "Vance Lucas", 1683 | "email": "vance@vancelucas.com", 1684 | "homepage": "http://www.vancelucas.com" 1685 | } 1686 | ], 1687 | "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", 1688 | "homepage": "http://github.com/vlucas/phpdotenv", 1689 | "keywords": [ 1690 | "dotenv", 1691 | "env", 1692 | "environment" 1693 | ], 1694 | "time": "2015-12-29T15:10:30+00:00" 1695 | } 1696 | ], 1697 | "packages-dev": [ 1698 | { 1699 | "name": "dflydev/markdown", 1700 | "version": "v1.0.0", 1701 | "source": { 1702 | "type": "git", 1703 | "url": "https://github.com/dflydev/dflydev-markdown.git", 1704 | "reference": "76501a808522dbe40a5a71d272bd08d54cbae03d" 1705 | }, 1706 | "dist": { 1707 | "type": "zip", 1708 | "url": "https://api.github.com/repos/dflydev/dflydev-markdown/zipball/76501a808522dbe40a5a71d272bd08d54cbae03d", 1709 | "reference": "76501a808522dbe40a5a71d272bd08d54cbae03d", 1710 | "shasum": "" 1711 | }, 1712 | "require": { 1713 | "php": ">=5.3" 1714 | }, 1715 | "type": "library", 1716 | "autoload": { 1717 | "psr-0": { 1718 | "dflydev\\markdown": "src" 1719 | } 1720 | }, 1721 | "notification-url": "https://packagist.org/downloads/", 1722 | "license": [ 1723 | "New BSD License" 1724 | ], 1725 | "authors": [ 1726 | { 1727 | "name": "Dragonfly Development Inc.", 1728 | "email": "info@dflydev.com", 1729 | "homepage": "http://dflydev.com" 1730 | }, 1731 | { 1732 | "name": "Beau Simensen", 1733 | "email": "beau@dflydev.com", 1734 | "homepage": "http://beausimensen.com" 1735 | }, 1736 | { 1737 | "name": "Michel Fortin", 1738 | "homepage": "http://michelf.com" 1739 | }, 1740 | { 1741 | "name": "John Gruber", 1742 | "homepage": "http://daringfireball.net" 1743 | } 1744 | ], 1745 | "description": "PHP Markdown & Extra", 1746 | "homepage": "http://github.com/dflydev/dflydev-markdown", 1747 | "keywords": [ 1748 | "markdown" 1749 | ], 1750 | "abandoned": "michelf/php-markdown", 1751 | "time": "2012-01-02T23:11:32+00:00" 1752 | }, 1753 | { 1754 | "name": "doctrine/instantiator", 1755 | "version": "1.0.4", 1756 | "source": { 1757 | "type": "git", 1758 | "url": "https://github.com/doctrine/instantiator.git", 1759 | "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" 1760 | }, 1761 | "dist": { 1762 | "type": "zip", 1763 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", 1764 | "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", 1765 | "shasum": "" 1766 | }, 1767 | "require": { 1768 | "php": ">=5.3,<8.0-DEV" 1769 | }, 1770 | "require-dev": { 1771 | "athletic/athletic": "~0.1.8", 1772 | "ext-pdo": "*", 1773 | "ext-phar": "*", 1774 | "phpunit/phpunit": "~4.0", 1775 | "squizlabs/php_codesniffer": "2.0.*@ALPHA" 1776 | }, 1777 | "type": "library", 1778 | "extra": { 1779 | "branch-alias": { 1780 | "dev-master": "1.0.x-dev" 1781 | } 1782 | }, 1783 | "autoload": { 1784 | "psr-0": { 1785 | "Doctrine\\Instantiator\\": "src" 1786 | } 1787 | }, 1788 | "notification-url": "https://packagist.org/downloads/", 1789 | "license": [ 1790 | "MIT" 1791 | ], 1792 | "authors": [ 1793 | { 1794 | "name": "Marco Pivetta", 1795 | "email": "ocramius@gmail.com", 1796 | "homepage": "http://ocramius.github.com/" 1797 | } 1798 | ], 1799 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 1800 | "homepage": "https://github.com/doctrine/instantiator", 1801 | "keywords": [ 1802 | "constructor", 1803 | "instantiate" 1804 | ], 1805 | "time": "2014-10-13T12:58:55+00:00" 1806 | }, 1807 | { 1808 | "name": "fzaninotto/faker", 1809 | "version": "v1.4.0", 1810 | "source": { 1811 | "type": "git", 1812 | "url": "https://github.com/fzaninotto/Faker.git", 1813 | "reference": "010c7efedd88bf31141a02719f51fb44c732d5a0" 1814 | }, 1815 | "dist": { 1816 | "type": "zip", 1817 | "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/010c7efedd88bf31141a02719f51fb44c732d5a0", 1818 | "reference": "010c7efedd88bf31141a02719f51fb44c732d5a0", 1819 | "shasum": "" 1820 | }, 1821 | "require": { 1822 | "php": ">=5.3.3" 1823 | }, 1824 | "require-dev": { 1825 | "phpunit/phpunit": "~4.0", 1826 | "squizlabs/php_codesniffer": "~1.5" 1827 | }, 1828 | "type": "library", 1829 | "extra": { 1830 | "branch-alias": [] 1831 | }, 1832 | "autoload": { 1833 | "psr-0": { 1834 | "Faker": "src/", 1835 | "Faker\\PHPUnit": "test/" 1836 | } 1837 | }, 1838 | "notification-url": "https://packagist.org/downloads/", 1839 | "license": [ 1840 | "MIT" 1841 | ], 1842 | "authors": [ 1843 | { 1844 | "name": "François Zaninotto" 1845 | } 1846 | ], 1847 | "description": "Faker is a PHP library that generates fake data for you.", 1848 | "keywords": [ 1849 | "data", 1850 | "faker", 1851 | "fixtures" 1852 | ], 1853 | "time": "2014-06-04T14:43:02+00:00" 1854 | }, 1855 | { 1856 | "name": "myclabs/deep-copy", 1857 | "version": "1.3.0", 1858 | "source": { 1859 | "type": "git", 1860 | "url": "https://github.com/myclabs/DeepCopy.git", 1861 | "reference": "96fbdc07635989c35c5a1912379f4c4b2ab15fd5" 1862 | }, 1863 | "dist": { 1864 | "type": "zip", 1865 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/96fbdc07635989c35c5a1912379f4c4b2ab15fd5", 1866 | "reference": "96fbdc07635989c35c5a1912379f4c4b2ab15fd5", 1867 | "shasum": "" 1868 | }, 1869 | "require": { 1870 | "php": ">=5.4.0" 1871 | }, 1872 | "require-dev": { 1873 | "doctrine/collections": "1.*", 1874 | "phpunit/phpunit": "~4.1" 1875 | }, 1876 | "type": "library", 1877 | "autoload": { 1878 | "psr-4": { 1879 | "DeepCopy\\": "src/DeepCopy/" 1880 | } 1881 | }, 1882 | "notification-url": "https://packagist.org/downloads/", 1883 | "license": [ 1884 | "MIT" 1885 | ], 1886 | "description": "Create deep copies (clones) of your objects", 1887 | "homepage": "https://github.com/myclabs/DeepCopy", 1888 | "keywords": [ 1889 | "clone", 1890 | "copy", 1891 | "duplicate", 1892 | "object", 1893 | "object graph" 1894 | ], 1895 | "time": "2015-03-21T22:40:23+00:00" 1896 | }, 1897 | { 1898 | "name": "orchestra/testbench", 1899 | "version": "v3.5.0", 1900 | "source": { 1901 | "type": "git", 1902 | "url": "https://github.com/orchestral/testbench.git", 1903 | "reference": "6d3fa0d98eb5ae012081aecfa4a6fb55df82b813" 1904 | }, 1905 | "dist": { 1906 | "type": "zip", 1907 | "url": "https://api.github.com/repos/orchestral/testbench/zipball/6d3fa0d98eb5ae012081aecfa4a6fb55df82b813", 1908 | "reference": "6d3fa0d98eb5ae012081aecfa4a6fb55df82b813", 1909 | "shasum": "" 1910 | }, 1911 | "require": { 1912 | "laravel/framework": "~5.5.0", 1913 | "orchestra/testbench-core": "~3.5.0", 1914 | "php": ">=7.0", 1915 | "phpunit/phpunit": "~6.0" 1916 | }, 1917 | "require-dev": { 1918 | "mockery/mockery": "^0.9.4", 1919 | "orchestra/database": "~3.5.0" 1920 | }, 1921 | "suggest": { 1922 | "orchestra/testbench-browser-kit": "Allow to use legacy BrowserKit for testing (~3.5)." 1923 | }, 1924 | "type": "library", 1925 | "extra": { 1926 | "branch-alias": { 1927 | "dev-master": "3.5-dev" 1928 | } 1929 | }, 1930 | "notification-url": "https://packagist.org/downloads/", 1931 | "license": [ 1932 | "MIT" 1933 | ], 1934 | "authors": [ 1935 | { 1936 | "name": "Mior Muhammad Zaki", 1937 | "email": "crynobone@gmail.com", 1938 | "homepage": "https://github.com/crynobone" 1939 | } 1940 | ], 1941 | "description": "Laravel Testing Helper for Packages Development", 1942 | "homepage": "http://orchestraplatform.com/docs/latest/components/testbench/", 1943 | "keywords": [ 1944 | "BDD", 1945 | "TDD", 1946 | "laravel", 1947 | "orchestra-platform", 1948 | "orchestral", 1949 | "testing" 1950 | ], 1951 | "time": "2017-08-25T10:17:08+00:00" 1952 | }, 1953 | { 1954 | "name": "orchestra/testbench-core", 1955 | "version": "v3.5.0", 1956 | "source": { 1957 | "type": "git", 1958 | "url": "https://github.com/orchestral/testbench-core.git", 1959 | "reference": "7afedcd1153e768dad7c832e268079d0d6a60f62" 1960 | }, 1961 | "dist": { 1962 | "type": "zip", 1963 | "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/7afedcd1153e768dad7c832e268079d0d6a60f62", 1964 | "reference": "7afedcd1153e768dad7c832e268079d0d6a60f62", 1965 | "shasum": "" 1966 | }, 1967 | "require": { 1968 | "fzaninotto/faker": "~1.4", 1969 | "php": ">=7.0" 1970 | }, 1971 | "require-dev": { 1972 | "laravel/framework": "~5.5.0", 1973 | "mockery/mockery": "^0.9.4", 1974 | "orchestra/database": "~3.5.0", 1975 | "phpunit/phpunit": "~6.0" 1976 | }, 1977 | "suggest": { 1978 | "laravel/framework": "Required for testing (~5.5.0).", 1979 | "mockery/mockery": "Allow to use Mockery for testing (^0.9.4).", 1980 | "orchestra/database": "Allow to use --realpath migration for testing (~3.5).", 1981 | "orchestra/testbench-browser-kit": "Allow to use legacy BrowserKit for testing (~3.5).", 1982 | "phpunit/phpunit": "Allow to use PHPUnit for testing (~6.0)." 1983 | }, 1984 | "type": "library", 1985 | "extra": { 1986 | "branch-alias": { 1987 | "dev-master": "3.5-dev" 1988 | } 1989 | }, 1990 | "autoload": { 1991 | "psr-4": { 1992 | "Orchestra\\Testbench\\": "src/" 1993 | } 1994 | }, 1995 | "notification-url": "https://packagist.org/downloads/", 1996 | "license": [ 1997 | "MIT" 1998 | ], 1999 | "authors": [ 2000 | { 2001 | "name": "Mior Muhammad Zaki", 2002 | "email": "crynobone@gmail.com", 2003 | "homepage": "https://github.com/crynobone" 2004 | } 2005 | ], 2006 | "description": "Testing Helper for Laravel Development", 2007 | "homepage": "http://orchestraplatform.com/docs/latest/components/testbench/", 2008 | "keywords": [ 2009 | "BDD", 2010 | "TDD", 2011 | "laravel", 2012 | "orchestra-platform", 2013 | "orchestral", 2014 | "testing" 2015 | ], 2016 | "time": "2017-08-25T10:40:49+00:00" 2017 | }, 2018 | { 2019 | "name": "phpdocumentor/reflection-docblock", 2020 | "version": "2.0.0", 2021 | "source": { 2022 | "type": "git", 2023 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 2024 | "reference": "66ae84e9d7c8ea85c979cb65977bd8e608baf0c5" 2025 | }, 2026 | "dist": { 2027 | "type": "zip", 2028 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/66ae84e9d7c8ea85c979cb65977bd8e608baf0c5", 2029 | "reference": "66ae84e9d7c8ea85c979cb65977bd8e608baf0c5", 2030 | "shasum": "" 2031 | }, 2032 | "require": { 2033 | "dflydev/markdown": "1.0.*", 2034 | "php": ">=5.3.3" 2035 | }, 2036 | "require-dev": { 2037 | "phpunit/phpunit": "3.7.*@stable" 2038 | }, 2039 | "type": "library", 2040 | "extra": { 2041 | "branch-alias": { 2042 | "dev-master": "2.0.x-dev" 2043 | } 2044 | }, 2045 | "autoload": { 2046 | "psr-0": { 2047 | "phpDocumentor": [ 2048 | "src/" 2049 | ] 2050 | } 2051 | }, 2052 | "notification-url": "https://packagist.org/downloads/", 2053 | "license": [ 2054 | "MIT" 2055 | ], 2056 | "authors": [ 2057 | { 2058 | "name": "Mike van Riel", 2059 | "email": "mike.vanriel@naenius.com" 2060 | } 2061 | ], 2062 | "time": "2013-08-07T11:04:22+00:00" 2063 | }, 2064 | { 2065 | "name": "phpspec/prophecy", 2066 | "version": "v1.6.2", 2067 | "source": { 2068 | "type": "git", 2069 | "url": "https://github.com/phpspec/prophecy.git", 2070 | "reference": "6c52c2722f8460122f96f86346600e1077ce22cb" 2071 | }, 2072 | "dist": { 2073 | "type": "zip", 2074 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb", 2075 | "reference": "6c52c2722f8460122f96f86346600e1077ce22cb", 2076 | "shasum": "" 2077 | }, 2078 | "require": { 2079 | "doctrine/instantiator": "^1.0.2", 2080 | "php": "^5.3|^7.0", 2081 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", 2082 | "sebastian/comparator": "^1.1", 2083 | "sebastian/recursion-context": "^1.0|^2.0" 2084 | }, 2085 | "require-dev": { 2086 | "phpspec/phpspec": "^2.0", 2087 | "phpunit/phpunit": "^4.8 || ^5.6.5" 2088 | }, 2089 | "type": "library", 2090 | "extra": { 2091 | "branch-alias": { 2092 | "dev-master": "1.6.x-dev" 2093 | } 2094 | }, 2095 | "autoload": { 2096 | "psr-0": { 2097 | "Prophecy\\": "src/" 2098 | } 2099 | }, 2100 | "notification-url": "https://packagist.org/downloads/", 2101 | "license": [ 2102 | "MIT" 2103 | ], 2104 | "authors": [ 2105 | { 2106 | "name": "Konstantin Kudryashov", 2107 | "email": "ever.zet@gmail.com", 2108 | "homepage": "http://everzet.com" 2109 | }, 2110 | { 2111 | "name": "Marcello Duarte", 2112 | "email": "marcello.duarte@gmail.com" 2113 | } 2114 | ], 2115 | "description": "Highly opinionated mocking framework for PHP 5.3+", 2116 | "homepage": "https://github.com/phpspec/prophecy", 2117 | "keywords": [ 2118 | "Double", 2119 | "Dummy", 2120 | "fake", 2121 | "mock", 2122 | "spy", 2123 | "stub" 2124 | ], 2125 | "time": "2016-11-21T14:58:47+00:00" 2126 | }, 2127 | { 2128 | "name": "phpunit/php-code-coverage", 2129 | "version": "5.0.0", 2130 | "source": { 2131 | "type": "git", 2132 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 2133 | "reference": "e7d7a4acca58e45bdfd00221563d131cfb04ba96" 2134 | }, 2135 | "dist": { 2136 | "type": "zip", 2137 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e7d7a4acca58e45bdfd00221563d131cfb04ba96", 2138 | "reference": "e7d7a4acca58e45bdfd00221563d131cfb04ba96", 2139 | "shasum": "" 2140 | }, 2141 | "require": { 2142 | "php": "^7.0", 2143 | "phpunit/php-file-iterator": "^1.3", 2144 | "phpunit/php-text-template": "^1.2", 2145 | "phpunit/php-token-stream": "^1.4.2", 2146 | "sebastian/code-unit-reverse-lookup": "^1.0", 2147 | "sebastian/environment": "^2.0", 2148 | "sebastian/version": "^2.0" 2149 | }, 2150 | "require-dev": { 2151 | "ext-xdebug": "^2.5", 2152 | "phpunit/phpunit": "^6.0" 2153 | }, 2154 | "suggest": { 2155 | "ext-dom": "*", 2156 | "ext-xmlwriter": "*" 2157 | }, 2158 | "type": "library", 2159 | "extra": { 2160 | "branch-alias": { 2161 | "dev-master": "5.0.x-dev" 2162 | } 2163 | }, 2164 | "autoload": { 2165 | "classmap": [ 2166 | "src/" 2167 | ] 2168 | }, 2169 | "notification-url": "https://packagist.org/downloads/", 2170 | "license": [ 2171 | "BSD-3-Clause" 2172 | ], 2173 | "authors": [ 2174 | { 2175 | "name": "Sebastian Bergmann", 2176 | "email": "sb@sebastian-bergmann.de", 2177 | "role": "lead" 2178 | } 2179 | ], 2180 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 2181 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 2182 | "keywords": [ 2183 | "coverage", 2184 | "testing", 2185 | "xunit" 2186 | ], 2187 | "time": "2017-02-02T10:35:41+00:00" 2188 | }, 2189 | { 2190 | "name": "phpunit/php-file-iterator", 2191 | "version": "1.4.0", 2192 | "source": { 2193 | "type": "git", 2194 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 2195 | "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb" 2196 | }, 2197 | "dist": { 2198 | "type": "zip", 2199 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a923bb15680d0089e2316f7a4af8f437046e96bb", 2200 | "reference": "a923bb15680d0089e2316f7a4af8f437046e96bb", 2201 | "shasum": "" 2202 | }, 2203 | "require": { 2204 | "php": ">=5.3.3" 2205 | }, 2206 | "type": "library", 2207 | "extra": { 2208 | "branch-alias": { 2209 | "dev-master": "1.4.x-dev" 2210 | } 2211 | }, 2212 | "autoload": { 2213 | "classmap": [ 2214 | "src/" 2215 | ] 2216 | }, 2217 | "notification-url": "https://packagist.org/downloads/", 2218 | "license": [ 2219 | "BSD-3-Clause" 2220 | ], 2221 | "authors": [ 2222 | { 2223 | "name": "Sebastian Bergmann", 2224 | "email": "sb@sebastian-bergmann.de", 2225 | "role": "lead" 2226 | } 2227 | ], 2228 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 2229 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 2230 | "keywords": [ 2231 | "filesystem", 2232 | "iterator" 2233 | ], 2234 | "time": "2015-04-02T05:19:05+00:00" 2235 | }, 2236 | { 2237 | "name": "phpunit/php-text-template", 2238 | "version": "1.2.0", 2239 | "source": { 2240 | "type": "git", 2241 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 2242 | "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" 2243 | }, 2244 | "dist": { 2245 | "type": "zip", 2246 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", 2247 | "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", 2248 | "shasum": "" 2249 | }, 2250 | "require": { 2251 | "php": ">=5.3.3" 2252 | }, 2253 | "type": "library", 2254 | "autoload": { 2255 | "classmap": [ 2256 | "Text/" 2257 | ] 2258 | }, 2259 | "notification-url": "https://packagist.org/downloads/", 2260 | "include-path": [ 2261 | "" 2262 | ], 2263 | "license": [ 2264 | "BSD-3-Clause" 2265 | ], 2266 | "authors": [ 2267 | { 2268 | "name": "Sebastian Bergmann", 2269 | "email": "sb@sebastian-bergmann.de", 2270 | "role": "lead" 2271 | } 2272 | ], 2273 | "description": "Simple template engine.", 2274 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 2275 | "keywords": [ 2276 | "template" 2277 | ], 2278 | "time": "2014-01-30T17:20:04+00:00" 2279 | }, 2280 | { 2281 | "name": "phpunit/php-timer", 2282 | "version": "1.0.6", 2283 | "source": { 2284 | "type": "git", 2285 | "url": "https://github.com/sebastianbergmann/php-timer.git", 2286 | "reference": "83fe1bdc5d47658b727595c14da140da92b3d66d" 2287 | }, 2288 | "dist": { 2289 | "type": "zip", 2290 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/83fe1bdc5d47658b727595c14da140da92b3d66d", 2291 | "reference": "83fe1bdc5d47658b727595c14da140da92b3d66d", 2292 | "shasum": "" 2293 | }, 2294 | "require": { 2295 | "php": ">=5.3.3" 2296 | }, 2297 | "type": "library", 2298 | "autoload": { 2299 | "classmap": [ 2300 | "src/" 2301 | ] 2302 | }, 2303 | "notification-url": "https://packagist.org/downloads/", 2304 | "license": [ 2305 | "BSD-3-Clause" 2306 | ], 2307 | "authors": [ 2308 | { 2309 | "name": "Sebastian Bergmann", 2310 | "email": "sb@sebastian-bergmann.de", 2311 | "role": "lead" 2312 | } 2313 | ], 2314 | "description": "Utility class for timing", 2315 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 2316 | "keywords": [ 2317 | "timer" 2318 | ], 2319 | "time": "2015-06-13T07:35:30+00:00" 2320 | }, 2321 | { 2322 | "name": "phpunit/php-token-stream", 2323 | "version": "1.4.2", 2324 | "source": { 2325 | "type": "git", 2326 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 2327 | "reference": "db63be1159c81df649cd0260e30249a586d4129e" 2328 | }, 2329 | "dist": { 2330 | "type": "zip", 2331 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db63be1159c81df649cd0260e30249a586d4129e", 2332 | "reference": "db63be1159c81df649cd0260e30249a586d4129e", 2333 | "shasum": "" 2334 | }, 2335 | "require": { 2336 | "ext-tokenizer": "*", 2337 | "php": ">=5.3.3" 2338 | }, 2339 | "require-dev": { 2340 | "phpunit/phpunit": "~4.2" 2341 | }, 2342 | "type": "library", 2343 | "extra": { 2344 | "branch-alias": { 2345 | "dev-master": "1.4-dev" 2346 | } 2347 | }, 2348 | "autoload": { 2349 | "classmap": [ 2350 | "src/" 2351 | ] 2352 | }, 2353 | "notification-url": "https://packagist.org/downloads/", 2354 | "license": [ 2355 | "BSD-3-Clause" 2356 | ], 2357 | "authors": [ 2358 | { 2359 | "name": "Sebastian Bergmann", 2360 | "email": "sebastian@phpunit.de" 2361 | } 2362 | ], 2363 | "description": "Wrapper around PHP's tokenizer extension.", 2364 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 2365 | "keywords": [ 2366 | "tokenizer" 2367 | ], 2368 | "time": "2015-06-12T07:34:24+00:00" 2369 | }, 2370 | { 2371 | "name": "phpunit/phpunit", 2372 | "version": "6.0.0", 2373 | "source": { 2374 | "type": "git", 2375 | "url": "https://github.com/sebastianbergmann/phpunit.git", 2376 | "reference": "9d0c024d2099531442d862b66b0ad7cf35ed8e78" 2377 | }, 2378 | "dist": { 2379 | "type": "zip", 2380 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9d0c024d2099531442d862b66b0ad7cf35ed8e78", 2381 | "reference": "9d0c024d2099531442d862b66b0ad7cf35ed8e78", 2382 | "shasum": "" 2383 | }, 2384 | "require": { 2385 | "ext-dom": "*", 2386 | "ext-json": "*", 2387 | "ext-libxml": "*", 2388 | "ext-mbstring": "*", 2389 | "ext-xml": "*", 2390 | "myclabs/deep-copy": "^1.3", 2391 | "php": "^7.0", 2392 | "phpspec/prophecy": "^1.6.2", 2393 | "phpunit/php-code-coverage": "^5.0", 2394 | "phpunit/php-file-iterator": "^1.4", 2395 | "phpunit/php-text-template": "^1.2", 2396 | "phpunit/php-timer": "^1.0.6", 2397 | "phpunit/phpunit-mock-objects": "^4.0", 2398 | "sebastian/comparator": "^1.2.4", 2399 | "sebastian/diff": "^1.2", 2400 | "sebastian/environment": "^2.0", 2401 | "sebastian/exporter": "^2.0", 2402 | "sebastian/global-state": "^1.1", 2403 | "sebastian/object-enumerator": "^2.0", 2404 | "sebastian/resource-operations": "^1.0", 2405 | "sebastian/version": "^2.0" 2406 | }, 2407 | "conflict": { 2408 | "phpdocumentor/reflection-docblock": "3.0.2", 2409 | "phpunit/dbunit": "<3.0" 2410 | }, 2411 | "require-dev": { 2412 | "ext-pdo": "*" 2413 | }, 2414 | "suggest": { 2415 | "ext-xdebug": "*", 2416 | "phpunit/php-invoker": "^1.1" 2417 | }, 2418 | "bin": [ 2419 | "phpunit" 2420 | ], 2421 | "type": "library", 2422 | "extra": { 2423 | "branch-alias": { 2424 | "dev-master": "6.0.x-dev" 2425 | } 2426 | }, 2427 | "autoload": { 2428 | "classmap": [ 2429 | "src/" 2430 | ] 2431 | }, 2432 | "notification-url": "https://packagist.org/downloads/", 2433 | "license": [ 2434 | "BSD-3-Clause" 2435 | ], 2436 | "authors": [ 2437 | { 2438 | "name": "Sebastian Bergmann", 2439 | "email": "sebastian@phpunit.de", 2440 | "role": "lead" 2441 | } 2442 | ], 2443 | "description": "The PHP Unit Testing framework.", 2444 | "homepage": "https://phpunit.de/", 2445 | "keywords": [ 2446 | "phpunit", 2447 | "testing", 2448 | "xunit" 2449 | ], 2450 | "time": "2017-02-03T05:22:46+00:00" 2451 | }, 2452 | { 2453 | "name": "phpunit/phpunit-mock-objects", 2454 | "version": "4.0.0", 2455 | "source": { 2456 | "type": "git", 2457 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 2458 | "reference": "3819745c44f3aff9518fd655f320c4535d541af7" 2459 | }, 2460 | "dist": { 2461 | "type": "zip", 2462 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3819745c44f3aff9518fd655f320c4535d541af7", 2463 | "reference": "3819745c44f3aff9518fd655f320c4535d541af7", 2464 | "shasum": "" 2465 | }, 2466 | "require": { 2467 | "doctrine/instantiator": "^1.0.2", 2468 | "php": "^7.0", 2469 | "phpunit/php-text-template": "^1.2", 2470 | "sebastian/exporter": "^2.0" 2471 | }, 2472 | "conflict": { 2473 | "phpunit/phpunit": "<6.0" 2474 | }, 2475 | "require-dev": { 2476 | "phpunit/phpunit": "^6.0" 2477 | }, 2478 | "suggest": { 2479 | "ext-soap": "*" 2480 | }, 2481 | "type": "library", 2482 | "extra": { 2483 | "branch-alias": { 2484 | "dev-master": "4.0.x-dev" 2485 | } 2486 | }, 2487 | "autoload": { 2488 | "classmap": [ 2489 | "src/" 2490 | ] 2491 | }, 2492 | "notification-url": "https://packagist.org/downloads/", 2493 | "license": [ 2494 | "BSD-3-Clause" 2495 | ], 2496 | "authors": [ 2497 | { 2498 | "name": "Sebastian Bergmann", 2499 | "email": "sb@sebastian-bergmann.de", 2500 | "role": "lead" 2501 | } 2502 | ], 2503 | "description": "Mock Object library for PHPUnit", 2504 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 2505 | "keywords": [ 2506 | "mock", 2507 | "xunit" 2508 | ], 2509 | "time": "2017-02-02T10:36:38+00:00" 2510 | }, 2511 | { 2512 | "name": "sebastian/code-unit-reverse-lookup", 2513 | "version": "1.0.0", 2514 | "source": { 2515 | "type": "git", 2516 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 2517 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" 2518 | }, 2519 | "dist": { 2520 | "type": "zip", 2521 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", 2522 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", 2523 | "shasum": "" 2524 | }, 2525 | "require": { 2526 | "php": ">=5.6" 2527 | }, 2528 | "require-dev": { 2529 | "phpunit/phpunit": "~5" 2530 | }, 2531 | "type": "library", 2532 | "extra": { 2533 | "branch-alias": { 2534 | "dev-master": "1.0.x-dev" 2535 | } 2536 | }, 2537 | "autoload": { 2538 | "classmap": [ 2539 | "src/" 2540 | ] 2541 | }, 2542 | "notification-url": "https://packagist.org/downloads/", 2543 | "license": [ 2544 | "BSD-3-Clause" 2545 | ], 2546 | "authors": [ 2547 | { 2548 | "name": "Sebastian Bergmann", 2549 | "email": "sebastian@phpunit.de" 2550 | } 2551 | ], 2552 | "description": "Looks up which function or method a line of code belongs to", 2553 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 2554 | "time": "2016-02-13T06:45:14+00:00" 2555 | }, 2556 | { 2557 | "name": "sebastian/comparator", 2558 | "version": "1.2.4", 2559 | "source": { 2560 | "type": "git", 2561 | "url": "https://github.com/sebastianbergmann/comparator.git", 2562 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" 2563 | }, 2564 | "dist": { 2565 | "type": "zip", 2566 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 2567 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 2568 | "shasum": "" 2569 | }, 2570 | "require": { 2571 | "php": ">=5.3.3", 2572 | "sebastian/diff": "~1.2", 2573 | "sebastian/exporter": "~1.2 || ~2.0" 2574 | }, 2575 | "require-dev": { 2576 | "phpunit/phpunit": "~4.4" 2577 | }, 2578 | "type": "library", 2579 | "extra": { 2580 | "branch-alias": { 2581 | "dev-master": "1.2.x-dev" 2582 | } 2583 | }, 2584 | "autoload": { 2585 | "classmap": [ 2586 | "src/" 2587 | ] 2588 | }, 2589 | "notification-url": "https://packagist.org/downloads/", 2590 | "license": [ 2591 | "BSD-3-Clause" 2592 | ], 2593 | "authors": [ 2594 | { 2595 | "name": "Jeff Welch", 2596 | "email": "whatthejeff@gmail.com" 2597 | }, 2598 | { 2599 | "name": "Volker Dusch", 2600 | "email": "github@wallbash.com" 2601 | }, 2602 | { 2603 | "name": "Bernhard Schussek", 2604 | "email": "bschussek@2bepublished.at" 2605 | }, 2606 | { 2607 | "name": "Sebastian Bergmann", 2608 | "email": "sebastian@phpunit.de" 2609 | } 2610 | ], 2611 | "description": "Provides the functionality to compare PHP values for equality", 2612 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 2613 | "keywords": [ 2614 | "comparator", 2615 | "compare", 2616 | "equality" 2617 | ], 2618 | "time": "2017-01-29T09:50:25+00:00" 2619 | }, 2620 | { 2621 | "name": "sebastian/diff", 2622 | "version": "1.2.0", 2623 | "source": { 2624 | "type": "git", 2625 | "url": "https://github.com/sebastianbergmann/diff.git", 2626 | "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" 2627 | }, 2628 | "dist": { 2629 | "type": "zip", 2630 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", 2631 | "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", 2632 | "shasum": "" 2633 | }, 2634 | "require": { 2635 | "php": ">=5.3.3" 2636 | }, 2637 | "require-dev": { 2638 | "phpunit/phpunit": "~4.2" 2639 | }, 2640 | "type": "library", 2641 | "extra": { 2642 | "branch-alias": { 2643 | "dev-master": "1.2-dev" 2644 | } 2645 | }, 2646 | "autoload": { 2647 | "classmap": [ 2648 | "src/" 2649 | ] 2650 | }, 2651 | "notification-url": "https://packagist.org/downloads/", 2652 | "license": [ 2653 | "BSD-3-Clause" 2654 | ], 2655 | "authors": [ 2656 | { 2657 | "name": "Kore Nordmann", 2658 | "email": "mail@kore-nordmann.de" 2659 | }, 2660 | { 2661 | "name": "Sebastian Bergmann", 2662 | "email": "sebastian@phpunit.de" 2663 | } 2664 | ], 2665 | "description": "Diff implementation", 2666 | "homepage": "http://www.github.com/sebastianbergmann/diff", 2667 | "keywords": [ 2668 | "diff" 2669 | ], 2670 | "time": "2014-08-15T10:29:00+00:00" 2671 | }, 2672 | { 2673 | "name": "sebastian/environment", 2674 | "version": "2.0.0", 2675 | "source": { 2676 | "type": "git", 2677 | "url": "https://github.com/sebastianbergmann/environment.git", 2678 | "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" 2679 | }, 2680 | "dist": { 2681 | "type": "zip", 2682 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", 2683 | "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", 2684 | "shasum": "" 2685 | }, 2686 | "require": { 2687 | "php": "^5.6 || ^7.0" 2688 | }, 2689 | "require-dev": { 2690 | "phpunit/phpunit": "^5.0" 2691 | }, 2692 | "type": "library", 2693 | "extra": { 2694 | "branch-alias": { 2695 | "dev-master": "2.0.x-dev" 2696 | } 2697 | }, 2698 | "autoload": { 2699 | "classmap": [ 2700 | "src/" 2701 | ] 2702 | }, 2703 | "notification-url": "https://packagist.org/downloads/", 2704 | "license": [ 2705 | "BSD-3-Clause" 2706 | ], 2707 | "authors": [ 2708 | { 2709 | "name": "Sebastian Bergmann", 2710 | "email": "sebastian@phpunit.de" 2711 | } 2712 | ], 2713 | "description": "Provides functionality to handle HHVM/PHP environments", 2714 | "homepage": "http://www.github.com/sebastianbergmann/environment", 2715 | "keywords": [ 2716 | "Xdebug", 2717 | "environment", 2718 | "hhvm" 2719 | ], 2720 | "time": "2016-11-26T07:53:53+00:00" 2721 | }, 2722 | { 2723 | "name": "sebastian/exporter", 2724 | "version": "2.0.0", 2725 | "source": { 2726 | "type": "git", 2727 | "url": "https://github.com/sebastianbergmann/exporter.git", 2728 | "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" 2729 | }, 2730 | "dist": { 2731 | "type": "zip", 2732 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", 2733 | "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", 2734 | "shasum": "" 2735 | }, 2736 | "require": { 2737 | "php": ">=5.3.3", 2738 | "sebastian/recursion-context": "~2.0" 2739 | }, 2740 | "require-dev": { 2741 | "ext-mbstring": "*", 2742 | "phpunit/phpunit": "~4.4" 2743 | }, 2744 | "type": "library", 2745 | "extra": { 2746 | "branch-alias": { 2747 | "dev-master": "2.0.x-dev" 2748 | } 2749 | }, 2750 | "autoload": { 2751 | "classmap": [ 2752 | "src/" 2753 | ] 2754 | }, 2755 | "notification-url": "https://packagist.org/downloads/", 2756 | "license": [ 2757 | "BSD-3-Clause" 2758 | ], 2759 | "authors": [ 2760 | { 2761 | "name": "Jeff Welch", 2762 | "email": "whatthejeff@gmail.com" 2763 | }, 2764 | { 2765 | "name": "Volker Dusch", 2766 | "email": "github@wallbash.com" 2767 | }, 2768 | { 2769 | "name": "Bernhard Schussek", 2770 | "email": "bschussek@2bepublished.at" 2771 | }, 2772 | { 2773 | "name": "Sebastian Bergmann", 2774 | "email": "sebastian@phpunit.de" 2775 | }, 2776 | { 2777 | "name": "Adam Harvey", 2778 | "email": "aharvey@php.net" 2779 | } 2780 | ], 2781 | "description": "Provides the functionality to export PHP variables for visualization", 2782 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 2783 | "keywords": [ 2784 | "export", 2785 | "exporter" 2786 | ], 2787 | "time": "2016-11-19T08:54:04+00:00" 2788 | }, 2789 | { 2790 | "name": "sebastian/global-state", 2791 | "version": "1.1.0", 2792 | "source": { 2793 | "type": "git", 2794 | "url": "https://github.com/sebastianbergmann/global-state.git", 2795 | "reference": "23af31f402993cfd94e99cbc4b782e9a78eb0e97" 2796 | }, 2797 | "dist": { 2798 | "type": "zip", 2799 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23af31f402993cfd94e99cbc4b782e9a78eb0e97", 2800 | "reference": "23af31f402993cfd94e99cbc4b782e9a78eb0e97", 2801 | "shasum": "" 2802 | }, 2803 | "require": { 2804 | "php": ">=5.3.3" 2805 | }, 2806 | "require-dev": { 2807 | "phpunit/phpunit": "~4.2" 2808 | }, 2809 | "suggest": { 2810 | "ext-uopz": "*" 2811 | }, 2812 | "type": "library", 2813 | "extra": { 2814 | "branch-alias": { 2815 | "dev-master": "1.0-dev" 2816 | } 2817 | }, 2818 | "autoload": { 2819 | "classmap": [ 2820 | "src/" 2821 | ] 2822 | }, 2823 | "notification-url": "https://packagist.org/downloads/", 2824 | "license": [ 2825 | "BSD-3-Clause" 2826 | ], 2827 | "authors": [ 2828 | { 2829 | "name": "Sebastian Bergmann", 2830 | "email": "sebastian@phpunit.de" 2831 | } 2832 | ], 2833 | "description": "Snapshotting of global state", 2834 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 2835 | "keywords": [ 2836 | "global state" 2837 | ], 2838 | "time": "2015-06-21T15:11:22+00:00" 2839 | }, 2840 | { 2841 | "name": "sebastian/object-enumerator", 2842 | "version": "2.0.0", 2843 | "source": { 2844 | "type": "git", 2845 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 2846 | "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35" 2847 | }, 2848 | "dist": { 2849 | "type": "zip", 2850 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", 2851 | "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", 2852 | "shasum": "" 2853 | }, 2854 | "require": { 2855 | "php": ">=5.6", 2856 | "sebastian/recursion-context": "~2.0" 2857 | }, 2858 | "require-dev": { 2859 | "phpunit/phpunit": "~5" 2860 | }, 2861 | "type": "library", 2862 | "extra": { 2863 | "branch-alias": { 2864 | "dev-master": "2.0.x-dev" 2865 | } 2866 | }, 2867 | "autoload": { 2868 | "classmap": [ 2869 | "src/" 2870 | ] 2871 | }, 2872 | "notification-url": "https://packagist.org/downloads/", 2873 | "license": [ 2874 | "BSD-3-Clause" 2875 | ], 2876 | "authors": [ 2877 | { 2878 | "name": "Sebastian Bergmann", 2879 | "email": "sebastian@phpunit.de" 2880 | } 2881 | ], 2882 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 2883 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 2884 | "time": "2016-11-19T07:35:10+00:00" 2885 | }, 2886 | { 2887 | "name": "sebastian/recursion-context", 2888 | "version": "2.0.0", 2889 | "source": { 2890 | "type": "git", 2891 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 2892 | "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" 2893 | }, 2894 | "dist": { 2895 | "type": "zip", 2896 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", 2897 | "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", 2898 | "shasum": "" 2899 | }, 2900 | "require": { 2901 | "php": ">=5.3.3" 2902 | }, 2903 | "require-dev": { 2904 | "phpunit/phpunit": "~4.4" 2905 | }, 2906 | "type": "library", 2907 | "extra": { 2908 | "branch-alias": { 2909 | "dev-master": "2.0.x-dev" 2910 | } 2911 | }, 2912 | "autoload": { 2913 | "classmap": [ 2914 | "src/" 2915 | ] 2916 | }, 2917 | "notification-url": "https://packagist.org/downloads/", 2918 | "license": [ 2919 | "BSD-3-Clause" 2920 | ], 2921 | "authors": [ 2922 | { 2923 | "name": "Jeff Welch", 2924 | "email": "whatthejeff@gmail.com" 2925 | }, 2926 | { 2927 | "name": "Sebastian Bergmann", 2928 | "email": "sebastian@phpunit.de" 2929 | }, 2930 | { 2931 | "name": "Adam Harvey", 2932 | "email": "aharvey@php.net" 2933 | } 2934 | ], 2935 | "description": "Provides functionality to recursively process PHP variables", 2936 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 2937 | "time": "2016-11-19T07:33:16+00:00" 2938 | }, 2939 | { 2940 | "name": "sebastian/resource-operations", 2941 | "version": "1.0.0", 2942 | "source": { 2943 | "type": "git", 2944 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 2945 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 2946 | }, 2947 | "dist": { 2948 | "type": "zip", 2949 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 2950 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 2951 | "shasum": "" 2952 | }, 2953 | "require": { 2954 | "php": ">=5.6.0" 2955 | }, 2956 | "type": "library", 2957 | "extra": { 2958 | "branch-alias": { 2959 | "dev-master": "1.0.x-dev" 2960 | } 2961 | }, 2962 | "autoload": { 2963 | "classmap": [ 2964 | "src/" 2965 | ] 2966 | }, 2967 | "notification-url": "https://packagist.org/downloads/", 2968 | "license": [ 2969 | "BSD-3-Clause" 2970 | ], 2971 | "authors": [ 2972 | { 2973 | "name": "Sebastian Bergmann", 2974 | "email": "sebastian@phpunit.de" 2975 | } 2976 | ], 2977 | "description": "Provides a list of PHP built-in functions that operate on resources", 2978 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 2979 | "time": "2015-07-28T20:34:47+00:00" 2980 | }, 2981 | { 2982 | "name": "sebastian/version", 2983 | "version": "2.0.0", 2984 | "source": { 2985 | "type": "git", 2986 | "url": "https://github.com/sebastianbergmann/version.git", 2987 | "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" 2988 | }, 2989 | "dist": { 2990 | "type": "zip", 2991 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", 2992 | "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", 2993 | "shasum": "" 2994 | }, 2995 | "require": { 2996 | "php": ">=5.6" 2997 | }, 2998 | "type": "library", 2999 | "extra": { 3000 | "branch-alias": { 3001 | "dev-master": "2.0.x-dev" 3002 | } 3003 | }, 3004 | "autoload": { 3005 | "classmap": [ 3006 | "src/" 3007 | ] 3008 | }, 3009 | "notification-url": "https://packagist.org/downloads/", 3010 | "license": [ 3011 | "BSD-3-Clause" 3012 | ], 3013 | "authors": [ 3014 | { 3015 | "name": "Sebastian Bergmann", 3016 | "email": "sebastian@phpunit.de", 3017 | "role": "lead" 3018 | } 3019 | ], 3020 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 3021 | "homepage": "https://github.com/sebastianbergmann/version", 3022 | "time": "2016-02-04T12:56:52+00:00" 3023 | } 3024 | ], 3025 | "aliases": [], 3026 | "minimum-stability": "stable", 3027 | "stability-flags": [], 3028 | "prefer-stable": true, 3029 | "prefer-lowest": true, 3030 | "platform": [], 3031 | "platform-dev": [] 3032 | } 3033 | -------------------------------------------------------------------------------- /config/modelmerge.php: -------------------------------------------------------------------------------- 1 | https://alariva.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /phpunit-travis.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | 18 | 19 | src/ 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | 18 | 19 | src/ 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # ModelMerge Laravel package 2 | 3 | [![Latest Stable Version](https://poser.pugx.org/alariva/modelmerge/v/stable?format=flat)](https://packagist.org/packages/alariva/modelmerge) 4 | [![Total Downloads](https://poser.pugx.org/alariva/modelmerge/downloads?format=flat)](https://packagist.org/packages/alariva/modelmerge) 5 | [![Latest Unstable Version](https://poser.pugx.org/alariva/modelmerge/v/unstable?format=flat)](https://packagist.org/packages/alariva/modelmerge) 6 | [![Build Status](https://travis-ci.org/alariva/laravel-modelmerge.svg?branch=master)](https://travis-ci.org/alariva/laravel-modelmerge) 7 | [![Maintainability](https://api.codeclimate.com/v1/badges/f8829aab2f787e403d3e/maintainability)](https://codeclimate.com/github/alariva/laravel-modelmerge/maintainability) 8 | [![Test Coverage](https://api.codeclimate.com/v1/badges/f8829aab2f787e403d3e/test_coverage)](https://codeclimate.com/github/alariva/laravel-modelmerge/test_coverage) 9 | [![License](https://poser.pugx.org/alariva/modelmerge/license?format=flat)](https://packagist.org/packages/alariva/modelmerge) 10 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Falariva%2Flaravel-modelmerge.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Falariva%2Flaravel-modelmerge?ref=badge_shield) 11 | 12 | Easy merging for Eloquent Models. 13 | 14 |

15 | 16 |

17 | 18 | ## Installation 19 | 20 | Via Composer 21 | 22 | ``` bash 23 | $ composer require alariva/modelmerge 24 | ``` 25 | 26 | ## Usage 27 | 28 | ```php 29 | $modelA = SampleModel::make(['firstname' => 'John', 'age' => 33]); 30 | $modelB = SampleModel::make(['firstname' => 'John', 'lastname' => 'Doe']); 31 | 32 | $mergedModel = ModelMerge::setModelA($modelA)->setModelB($modelB)->merge(); 33 | 34 | $mergedModel->firstname; // John 35 | $mergedModel->lastname; // Doe 36 | $mergedModel->age; // 33 37 | ``` 38 | 39 | ## Change log 40 | 41 | Please see the [changelog](changelog.md) for more information on what has changed recently. 42 | 43 | ## Testing 44 | 45 | ``` bash 46 | $ composer test 47 | ``` 48 | 49 | ## Contributing 50 | 51 | Please see [contributing.md](contributing.md) for details and a todolist. 52 | 53 | ## Security 54 | 55 | If you discover any security related issues, please email author email instead of using the issue tracker. 56 | 57 | ## Credits 58 | 59 | - [Ariel Vallese](https://alariva.com) 60 | - Icons made by [Freepik](http://www.freepik.com) from [Flaticon](http://www.flaticon.com) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/) 61 | - Icons made by [Roundicons](https://www.flaticon.com/authors/roundicons) from [Flaticon](http://www.flaticon.com) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/) 62 | 63 | ## License 64 | 65 | MIT. Please see the [license file](license.md) for more information. 66 | 67 | 68 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Falariva%2Flaravel-modelmerge.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Falariva%2Flaravel-modelmerge?ref=badge_large) -------------------------------------------------------------------------------- /src/Exceptions/ModelsBelongToDivergedParentsException.php: -------------------------------------------------------------------------------- 1 | useStrategy($strategy); 58 | } 59 | 60 | /** 61 | * Pick a strategy class for merge operation. 62 | * 63 | * @param Alariva\ModelMerge\Strategies\ModelMergeStrategy $strategy Instance of a merger strategy 64 | * 65 | * @return $this 66 | */ 67 | public function useStrategy(ModelMergeStrategy $strategy = null) 68 | { 69 | $this->strategy = $strategy === null ? new MergeSimple() : $strategy; 70 | 71 | return $this; 72 | } 73 | 74 | /** 75 | * Set model A 76 | * 77 | * @param Model $model 78 | * 79 | * @return $this 80 | */ 81 | public function setModelA(Model $model) 82 | { 83 | $this->modelA = $model; 84 | 85 | return $this; 86 | } 87 | 88 | public function getModelA() 89 | { 90 | return $this->modelA; 91 | } 92 | 93 | public function getModelB() 94 | { 95 | return $this->modelB; 96 | } 97 | 98 | public function getBase() 99 | { 100 | return $this->getModelA(); 101 | } 102 | 103 | public function getDupe() 104 | { 105 | return $this->getModelB(); 106 | } 107 | 108 | /** 109 | * Set model B 110 | * 111 | * @param Model $model 112 | * 113 | * @return $this 114 | */ 115 | public function setModelB(Model $model) 116 | { 117 | $this->modelB = $model; 118 | 119 | return $this; 120 | } 121 | 122 | /** 123 | * Alias for setModelA 124 | * 125 | * @param Model $baseModel 126 | */ 127 | public function setBase($baseModel) 128 | { 129 | $this->setModelA($baseModel); 130 | 131 | return $this; 132 | } 133 | 134 | /** 135 | * Alias for setModelB 136 | * 137 | * @param Model $dupeModel 138 | */ 139 | public function setDupe($dupeModel) 140 | { 141 | $this->setModelB($dupeModel); 142 | 143 | return $this; 144 | } 145 | 146 | /** 147 | * Specify a compound key to match models and verify identity. 148 | * 149 | * @param string|array $keys Keys that make the model identifiable 150 | * 151 | * @return $this 152 | */ 153 | public function withKey($keys) 154 | { 155 | if (is_array($keys)) { 156 | $this->keys = $keys; 157 | } 158 | 159 | if (is_string($keys)) { 160 | $this->keys = [$keys]; 161 | } 162 | 163 | return $this; 164 | } 165 | 166 | /** 167 | * Executes the merge for A and B Models 168 | * 169 | * @return Illuminate\Database\Eloquent\Model The model A with merged attributes from model B 170 | */ 171 | public function merge() 172 | { 173 | $this->validateKeys(); 174 | 175 | $this->validateBelongsToSameParent(); 176 | 177 | $this->transferRelationships(); 178 | 179 | return $this->strategy->merge($this->modelA, $this->modelB); 180 | } 181 | 182 | /** 183 | * Executes the merge and performs save/delete accordingly to preserve base and discard dupe 184 | * 185 | * @return Illuminate\Database\Eloquent\Model The model A (base) 186 | */ 187 | public function unifyOnBase() 188 | { 189 | $mergeModel = $this->merge(); 190 | 191 | $this->modelA->fill($mergeModel->toArray()); 192 | 193 | $this->modelA->save(); 194 | 195 | $this->modelB->delete(); 196 | 197 | return $this->modelA; 198 | } 199 | 200 | /** 201 | * Prefer the oldest of the models to be preserved 202 | * 203 | * @return $this 204 | */ 205 | public function preferOldest() 206 | { 207 | if ($this->modelB->created_at < $this->modelA->created_at) { 208 | $this->swapPriority(); 209 | } 210 | 211 | return $this; 212 | } 213 | 214 | /** 215 | * Prefer the newest of the models to be preserved 216 | * 217 | * @return $this 218 | */ 219 | public function preferNewest() 220 | { 221 | if ($this->modelB->created_at > $this->modelA->created_at) { 222 | $this->swapPriority(); 223 | } 224 | 225 | return $this; 226 | } 227 | 228 | /** 229 | * Swap models from base to dupe and vice versa 230 | * 231 | * @return $this 232 | */ 233 | public function swapPriority() 234 | { 235 | $tmp = $this->modelA; 236 | 237 | $this->modelA = $this->modelB; 238 | $this->modelB = $tmp; 239 | 240 | return $this; 241 | } 242 | 243 | public function belongsTo($belongsTo = null) 244 | { 245 | $this->belongsTo = $belongsTo; 246 | 247 | return $this; 248 | } 249 | 250 | /** 251 | * Alias for belongsTo 252 | * 253 | * @param string $belongsTo Relationship name 254 | * @return $this 255 | */ 256 | public function mustBelongToSame($belongsTo = null) 257 | { 258 | return $this->belongsTo($belongsTo); 259 | } 260 | 261 | public function withRelationships(array $relationships) 262 | { 263 | $this->relationships = $relationships; 264 | 265 | return $this; 266 | } 267 | 268 | public function transferRelationships() 269 | { 270 | foreach ($this->relationships as $relationship) { 271 | $this->transferChilds($relationship); 272 | } 273 | } 274 | 275 | public function transferChilds($relationship) 276 | { 277 | foreach ($this->modelB->$relationship as $child) { 278 | $this->modelA->$relationship()->save($child); 279 | } 280 | } 281 | 282 | protected function validateKeys() 283 | { 284 | if ($this->keys === null) { 285 | return; 286 | } 287 | 288 | $dataA = $this->modelA->only($this->keys); 289 | $dataB = $this->modelB->only($this->keys); 290 | 291 | if ($dataA != $dataB) { 292 | throw new ModelsNotDupeException('Models are not dupes', 1); 293 | } 294 | } 295 | 296 | protected function validateBelongsToSameParent() 297 | { 298 | if ($this->belongsTo === null) { 299 | return; 300 | } 301 | 302 | if ($this->modelA->{$this->belongsTo} != $this->modelB->{$this->belongsTo}) { 303 | throw new ModelsBelongToDivergedParentsException('Models do not belong to same parent', 1); 304 | } 305 | } 306 | } 307 | -------------------------------------------------------------------------------- /src/ModelMergeServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 18 | 19 | // Publishing the configuration file. 20 | $this->publishes([ 21 | __DIR__.'/../config/modelmerge.php' => config_path('modelmerge.php'), 22 | ], 'modelmerge.config'); 23 | 24 | // Registering package commands. 25 | // $this->commands([]); 26 | } 27 | } 28 | 29 | /** 30 | * Register any package services. 31 | * 32 | * @return void 33 | */ 34 | public function register() 35 | { 36 | $this->mergeConfigFrom(__DIR__.'/../config/modelmerge.php', 'modelmerge'); 37 | 38 | // Register the service the package provides. 39 | $this->app->singleton('modelmerge', function ($app) { 40 | return new ModelMerge; 41 | }); 42 | } 43 | 44 | /** 45 | * Get the services provided by the provider. 46 | * 47 | * @return array 48 | */ 49 | public function provides() 50 | { 51 | return ['modelmerge']; 52 | } 53 | } -------------------------------------------------------------------------------- /src/Strategies/MergeSimple.php: -------------------------------------------------------------------------------- 1 | toArray(); 12 | $dataB = $modelB->toArray(); 13 | 14 | $dataMerge = array_merge($dataB, $dataA); 15 | 16 | $modelA->fill($dataMerge); 17 | 18 | return $modelA; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Strategies/ModelMergeStrategy.php: -------------------------------------------------------------------------------- 1 | addConnection([ 20 | 'driver' => 'sqlite', 21 | 'database' => ':memory:' 22 | ]); 23 | 24 | $capsule->setAsGlobal(); 25 | $capsule->bootEloquent(); 26 | 27 | Capsule::schema()->create('dummy_contacts', function (Blueprint $table) { 28 | $table->increments('id'); 29 | $table->string('firstname'); 30 | $table->string('lastname'); 31 | $table->string('age')->nullable(); 32 | $table->string('eyes')->nullable(); 33 | $table->string('phone')->nullable(); 34 | $table->string('address')->nullable(); 35 | $table->timestamps(); 36 | }); 37 | 38 | Capsule::schema()->create('dummy_sheep', function (Blueprint $table) { 39 | $table->increments('id'); 40 | $table->integer('dummy_contact_id'); 41 | $table->string('name'); 42 | $table->string('color')->nullable(); 43 | $table->timestamps(); 44 | }); 45 | } 46 | 47 | /** 48 | * Load package service provider 49 | * 50 | * @param \Illuminate\Foundation\Application $app 51 | * 52 | * @return Alariva\EmailDomainBlacklist\ModelMergeServiceProvider 53 | */ 54 | protected function getPackageProviders($app) 55 | { 56 | return [ModelMergeServiceProvider::class]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/DummyContact.php: -------------------------------------------------------------------------------- 1 | hasMany(DummySheep::class); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/DummySheep.php: -------------------------------------------------------------------------------- 1 | belongsTo(DummyContact::class, 'dummy_contact_id'); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/ModelMergeFacadeTest.php: -------------------------------------------------------------------------------- 1 | 'John', 'age' => 33]); 13 | $modelB = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe']); 14 | 15 | $mergedModel = ModelMerge::setModelA($modelA)->setModelB($modelB)->merge(); 16 | 17 | $this->assertInstanceOf(Model::class, $mergedModel, 'Merged model should extend an Eloquent Model'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/ModelMergeRelationshipsTest.php: -------------------------------------------------------------------------------- 1 | 'John', 13 | 'lastname' => 'Doe', 14 | 'age' => 33, 15 | 'phone' => '+1 123 456 789', 16 | 'created_at' => Carbon::now(), ]); 17 | $newestModel = DummyContact::create(['firstname' => 'John', 18 | 'lastname' => 'Doe', 19 | 'age' => 33, 20 | 'created_at' => Carbon::now()->addDay(), ]); 21 | 22 | $sheepDolly = DummySheep::make(['name' => 'Dolly', 'color' => 'white']); 23 | $sheepMolly = DummySheep::make(['name' => 'Molly', 'color' => 'gray']); 24 | $sheepRoberta = DummySheep::make(['name' => 'Roberta', 'color' => 'black']); 25 | 26 | $newestModel->sheeps()->save($sheepDolly); 27 | $newestModel->sheeps()->save($sheepMolly); 28 | $newestModel->sheeps()->save($sheepRoberta); 29 | 30 | $modelMerge = new ModelMerge(); 31 | 32 | $this->assertEquals($oldestModel->sheeps()->count(), 0); 33 | $this->assertEquals($newestModel->sheeps()->count(), 3); 34 | 35 | $mergedModel = $modelMerge->withRelationships(['sheeps']) 36 | ->setBase($oldestModel) 37 | ->setDupe($newestModel) 38 | ->merge(); 39 | 40 | // Merge was correct 41 | $this->assertEquals($mergedModel->firstname, 'John'); 42 | $this->assertEquals($mergedModel->lastname, 'Doe'); 43 | $this->assertEquals($mergedModel->age, 33); 44 | $this->assertEquals($mergedModel->phone, '+1 123 456 789'); 45 | 46 | // Child models were transferred 47 | $this->assertEquals($oldestModel->sheeps()->count(), 3); 48 | $this->assertEquals($newestModel->sheeps()->count(), 0); 49 | 50 | // And total count of child models was preserved 51 | $this->assertEquals(DummySheep::count(), 3); 52 | } 53 | 54 | public function test_it_aborts_merge_on_belong_to_diverge() 55 | { 56 | $shepherdJohn = DummyContact::create(['firstname' => 'John', 57 | 'lastname' => 'Doe',]); 58 | $shepherdMatt = DummyContact::create(['firstname' => 'Matt', 59 | 'lastname' => 'Power',]); 60 | 61 | $sheepWhiteDolly = DummySheep::make(['name' => 'Dolly', 'color' => 'white']); 62 | $sheepBlackDolly = DummySheep::make(['name' => 'Dolly', 'color' => 'black']); 63 | 64 | $shepherdJohn->sheeps()->save($sheepWhiteDolly); 65 | $shepherdMatt->sheeps()->save($sheepBlackDolly); 66 | 67 | $modelMerge = new ModelMerge(); 68 | 69 | $this->assertEquals($shepherdJohn->sheeps()->count(), 1); 70 | $this->assertEquals($shepherdMatt->sheeps()->count(), 1); 71 | 72 | $this->expectException(\Alariva\ModelMerge\Exceptions\ModelsBelongToDivergedParentsException::class); 73 | 74 | $mergedModel = $modelMerge->mustBelongToSame('owner') 75 | ->setBase($sheepWhiteDolly) 76 | ->setDupe($sheepBlackDolly) 77 | ->unifyOnBase(); 78 | 79 | // Relationships were untouched 80 | $this->assertEquals($shepherdJohn->sheeps()->count(), 1); 81 | $this->assertEquals($shepherdMatt->sheeps()->count(), 1); 82 | 83 | // And total count of child models was preserved 84 | $this->assertEquals(DummySheep::count(), 2); 85 | } 86 | 87 | public function test_it_merges_on_belong_to_same_parent() 88 | { 89 | $shepherd = DummyContact::create(['firstname' => 'John', 90 | 'lastname' => 'Doe',]); 91 | 92 | $sheepBaseDolly = DummySheep::make(['name' => 'Dolly', 'color' => 'white']); 93 | $sheepDupeDolly = DummySheep::make(['name' => 'Dolly', 'color' => 'white']); 94 | 95 | $shepherd->sheeps()->save($sheepBaseDolly); 96 | $shepherd->sheeps()->save($sheepDupeDolly); 97 | 98 | $modelMerge = new ModelMerge(); 99 | 100 | $this->assertEquals($shepherd->sheeps()->count(), 2); 101 | 102 | $mergedModel = $modelMerge->mustBelongToSame('owner') 103 | ->setBase($sheepBaseDolly) 104 | ->setDupe($sheepDupeDolly) 105 | ->unifyOnBase(); 106 | 107 | // Merge was correct 108 | $this->assertEquals($mergedModel->name, 'Dolly'); 109 | $this->assertEquals($mergedModel->color, 'white'); 110 | $this->assertEquals($mergedModel->owner->id, $shepherd->id); 111 | 112 | // Relationships were untouched 113 | $this->assertEquals($shepherd->sheeps()->count(), 1); 114 | 115 | // And total count of child models was preserved 116 | $this->assertEquals(DummySheep::count(), 1); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /tests/ModelMergeStrategiesTest.php: -------------------------------------------------------------------------------- 1 | 'John', 'age' => 33]); 14 | $modelB = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe']); 15 | 16 | $modelMerge = new ModelMerge(new MergeSimple); 17 | $modelMerge->setModelA($modelA)->setModelB($modelB); 18 | $mergedModel = $modelMerge->merge(); 19 | 20 | $this->assertEquals($mergedModel->firstname, 'John'); 21 | $this->assertEquals($mergedModel->lastname, 'Doe'); 22 | $this->assertEquals($mergedModel->age, 33); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/ModelMergeTest.php: -------------------------------------------------------------------------------- 1 | 'John']); 15 | $modelB = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe']); 16 | 17 | $modelMerge = new ModelMerge(); 18 | $modelMerge->setModelA($modelA)->setModelB($modelB); 19 | $mergedModel = $modelMerge->merge(); 20 | 21 | $this->assertInstanceOf(Model::class, $mergedModel, 'Merged model should extend an Eloquent Model'); 22 | } 23 | 24 | public function test_it_provides_getter_for_base() 25 | { 26 | $modelA = DummyContact::make(['firstname' => 'John']); 27 | $modelB = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe']); 28 | 29 | $modelMerge = new ModelMerge(); 30 | $modelMerge->setModelA($modelA)->setModelB($modelB); 31 | $baseModel = $modelMerge->getBase(); 32 | 33 | $this->assertInstanceOf(Model::class, $baseModel); 34 | $this->assertEquals($modelA, $baseModel); 35 | } 36 | 37 | public function test_it_provides_getter_for_dupe() 38 | { 39 | $modelA = DummyContact::make(['firstname' => 'John']); 40 | $modelB = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe']); 41 | 42 | $modelMerge = new ModelMerge(); 43 | $modelMerge->setModelA($modelA)->setModelB($modelB); 44 | $dupeModel = $modelMerge->getdupe(); 45 | 46 | $this->assertInstanceOf(Model::class, $dupeModel); 47 | $this->assertEquals($modelB, $dupeModel); 48 | } 49 | 50 | public function test_it_performs_a_valid_merge() 51 | { 52 | $modelA = DummyContact::make(['firstname' => 'John', 'age' => 33]); 53 | $modelB = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe']); 54 | 55 | $modelMerge = new ModelMerge(); 56 | $modelMerge->setModelA($modelA)->setModelB($modelB); 57 | $mergedModel = $modelMerge->merge(); 58 | 59 | $this->assertEquals($mergedModel->firstname, 'John'); 60 | $this->assertEquals($mergedModel->lastname, 'Doe'); 61 | $this->assertEquals($mergedModel->age, 33); 62 | } 63 | 64 | public function test_it_allows_an_external_strategy_class() 65 | { 66 | $modelA = DummyContact::make(['firstname' => 'John', 'age' => 33]); 67 | $modelB = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe']); 68 | 69 | $strategy = new MergeSimple(); 70 | 71 | $modelMerge = new ModelMerge($strategy); 72 | $modelMerge->setModelA($modelA)->setModelB($modelB); 73 | $mergedModel = $modelMerge->merge(); 74 | 75 | $this->assertEquals($mergedModel->firstname, 'John'); 76 | $this->assertEquals($mergedModel->lastname, 'Doe'); 77 | $this->assertEquals($mergedModel->age, 33); 78 | } 79 | 80 | public function test_it_verifies_nok_identity_compound_key_before_merge() 81 | { 82 | $modelA = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe', 'age' => 33]); 83 | $modelB = DummyContact::make(['firstname' => 'John', 'lastname' => 'Other', 'age' => 33, 'phone' => '+1 123 456 789']); 84 | 85 | $modelMerge = new ModelMerge(new MergeSimple()); 86 | $modelMerge->withKey(['firstname', 'lastname', 'age'])->setModelA($modelA)->setModelB($modelB); 87 | 88 | $this->expectException(\Alariva\ModelMerge\Exceptions\ModelsNotDupeException::class); 89 | 90 | $mergedModel = $modelMerge->merge(); 91 | } 92 | 93 | public function test_it_verifies_nok_identity_compound_key_before_merge_passed_as_string() 94 | { 95 | $modelA = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe', 'age' => 33]); 96 | $modelB = DummyContact::make(['firstname' => 'John', 'lastname' => 'Other', 'age' => 33, 'phone' => '+1 123 456 789']); 97 | 98 | $modelMerge = new ModelMerge(new MergeSimple()); 99 | $modelMerge->withKey('lastname')->setModelA($modelA)->setModelB($modelB); 100 | 101 | $this->expectException(\Alariva\ModelMerge\Exceptions\ModelsNotDupeException::class); 102 | 103 | $mergedModel = $modelMerge->merge(); 104 | } 105 | 106 | public function test_it_verifies_ok_identity_compound_key_before_merge_passed_as_string() 107 | { 108 | $modelA = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe', 'age' => 33]); 109 | $modelB = DummyContact::make(['firstname' => 'John', 'lastname' => 'Doe', 'age' => 33, 'phone' => '+1 123 456 789']); 110 | 111 | $modelMerge = new ModelMerge(new MergeSimple()); 112 | $modelMerge->withKey('lastname')->setModelA($modelA)->setModelB($modelB); 113 | 114 | $mergedModel = $modelMerge->merge(); 115 | 116 | $this->assertEquals($mergedModel->firstname, 'John'); 117 | $this->assertEquals($mergedModel->lastname, 'Doe'); 118 | $this->assertEquals($mergedModel->age, 33); 119 | } 120 | 121 | public function test_it_saves_the_merged_model() 122 | { 123 | $baseModel = DummyContact::create(['firstname' => 'John', 'lastname' => 'Doe', 'age' => 33]); 124 | $dupeModel = DummyContact::create(['firstname' => 'John', 'lastname' => 'Doe', 'age' => 33, 'phone' => '+1 123 456 789']); 125 | 126 | $modelMerge = new ModelMerge(); 127 | $baseModel = $modelMerge->setBase($baseModel)->setDupe($dupeModel)->unifyOnBase(); 128 | 129 | // Merge was correct 130 | $this->assertEquals($baseModel->firstname, 'John'); 131 | $this->assertEquals($baseModel->lastname, 'Doe'); 132 | $this->assertEquals($baseModel->age, 33); 133 | $this->assertEquals($baseModel->phone, '+1 123 456 789'); 134 | 135 | // Base was saved and dupe was deleted 136 | $this->assertEquals(true, $baseModel->exists); 137 | $this->assertEquals(false, $dupeModel->exists); 138 | } 139 | 140 | public function test_it_can_prefer_newest_record() 141 | { 142 | $oldestModel = DummyContact::create(['firstname' => 'John', 143 | 'lastname' => 'Doe', 144 | 'age' => 33, 145 | 'created_at' => Carbon::now(), ]); 146 | $newestModel = DummyContact::create(['firstname' => 'John', 147 | 'lastname' => 'Doe', 148 | 'age' => 34, 149 | 'phone' => '+1 123 456 789', 150 | 'created_at' => Carbon::now()->addDay(), ]); 151 | 152 | $modelMerge = new ModelMerge(); 153 | 154 | $modelA = $modelMerge->setBase($oldestModel)->setDupe($newestModel)->preferNewest()->getBase(); 155 | 156 | // Merge was correct 157 | $this->assertEquals($modelA->firstname, 'John'); 158 | $this->assertEquals($modelA->lastname, 'Doe'); 159 | $this->assertEquals($modelA->age, 34); 160 | } 161 | 162 | public function test_it_can_prefer_oldest_record() 163 | { 164 | $oldestModel = DummyContact::create(['firstname' => 'John', 165 | 'lastname' => 'Doe', 166 | 'age' => 33, 167 | 'created_at' => Carbon::now(), ]); 168 | $newestModel = DummyContact::create(['firstname' => 'John', 169 | 'lastname' => 'Doe', 170 | 'age' => 34, 171 | 'phone' => '+1 123 456 789', 172 | 'created_at' => Carbon::now()->addDay(), ]); 173 | 174 | $modelMerge = new ModelMerge(); 175 | 176 | $modelA = $modelMerge->setBase($oldestModel)->setDupe($newestModel)->preferOldest()->getBase(); 177 | 178 | // Merge was correct 179 | $this->assertEquals($modelA->firstname, 'John'); 180 | $this->assertEquals($modelA->lastname, 'Doe'); 181 | $this->assertEquals($modelA->age, 33); 182 | } 183 | 184 | public function test_it_merges_correctly_after_swap() 185 | { 186 | $oldestModel = DummyContact::create(['firstname' => 'John', 187 | 'lastname' => 'Doe', 188 | 'age' => 33, 189 | 'phone' => '+1 123 456 789', 190 | 'created_at' => Carbon::now(), ]); 191 | $newestModel = DummyContact::create(['firstname' => 'John', 192 | 'lastname' => 'Doe', 193 | 'age' => 34, 194 | 'created_at' => Carbon::now()->addDay(), ]); 195 | 196 | $modelMerge = new ModelMerge(); 197 | 198 | $mergedModel = $modelMerge->setBase($oldestModel)->setDupe($newestModel)->swapPriority()->merge(); 199 | 200 | // Merge was correct 201 | $this->assertEquals($mergedModel->firstname, 'John'); 202 | $this->assertEquals($mergedModel->lastname, 'Doe'); 203 | $this->assertEquals($mergedModel->age, 34); 204 | $this->assertEquals($mergedModel->phone, '+1 123 456 789'); 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 |