├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── bin └── slimapi ├── box.json ├── composer.json ├── composer.lock ├── config ├── commands.config.php └── services.config.php ├── phpunit.xml.dist ├── src ├── Command │ ├── GenerateCommand.php │ ├── InitCommand.php │ ├── InitDbCommand.php │ └── RoutesCommand.php ├── Factory │ └── GeneratorFactory.php ├── Generator │ └── GeneratorInterface.php ├── Interfaces │ └── GeneratorServiceInterface.php ├── Migration │ └── MigrationInterface.php ├── Model │ └── ModelInterface.php ├── Module.php ├── Service │ ├── ConfigService.php │ ├── DependencyService.php │ ├── ModuleService.php │ └── RouteService.php ├── Skeleton │ ├── SkeletonInterface.php │ └── SkeletonService.php ├── application.php └── bootstrap.php └── tests └── phpunit ├── Command ├── GenerateCommandTest.php ├── InitCommandTest.php ├── InitDbCommandTest.php └── RoutesCommandTest.php ├── DirectoryTrait.php ├── Factory └── GeneratorFactoryTest.php ├── Mock └── ModelGeneratorMock.php ├── Service ├── ConfigServiceTest.php ├── DependencyServiceTest.php └── RouteServiceTest.php ├── Skeleton └── SkeletonServiceTest.php ├── bootstrap.php └── output └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | build/* 3 | tests/phpunit/output/* 4 | !tests/phpunit/output/.gitkeep 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.6 5 | - 7.0 6 | - hhvm 7 | 8 | install: 9 | - composer install 10 | 11 | script: vendor/bin/phpunit 12 | 13 | after_script: 14 | - php vendor/bin/coveralls 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Gabriel Baker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #slim-api 2 | Basic slim api project and generator 3 | 4 | [![Coverage Status](https://coveralls.io/repos/slimphp-api/slim-api/badge.svg?branch=master&service=github)](https://coveralls.io/github/slimphp-api/slim-api?branch=master) 5 | [![Code Climate](https://codeclimate.com/github/slimphp-api/slim-api/badges/gpa.svg)](https://codeclimate.com/github/slimphp-api/slim-api) 6 | [![Build Status](https://travis-ci.org/slimphp-api/slim-api.svg)](https://travis-ci.org/slimphp-api/slim-api) 7 | 8 | #Status 9 | 10 | Alpha, init and create models/controllers/scaffolds is complete. 11 | 12 | #What? 13 | 14 | A simple command line app for producing simple controllers/models/migrations, routes and DI, using Slim and symfony console. 15 | 16 | ###External modules 17 | By default the app uses phinx and eloquent for migrations and ORM, these are provided by external modules: [slim-eloquent](https://github.com/slimphp-api/slim-eloquent) and [slim-phinx](https://github.com/slimphp-api/slim-phinx) 18 | 19 | #Why? 20 | 21 | I wanted to be able to create API end points as easily as possible, and I love the simplicity of Slim, and after a sordid time with RoR this seemed like a fun thing to do! 22 | 23 | #How? 24 | 25 | ###Installation 26 | 27 | Install globally within your user account `composer global require slimphp-api/slim-api dev-master` 28 | Make sure global composer is in your path `export PATH=~/.composer/vendor/bin:$PATH` in .bashrc 29 | 30 | 31 | ###Init 32 | 33 | Basic useage is simple, we first have to initiate the project, this creates a default skeleton for the project and initiates the phinx configuration. 34 | 35 | ``` 36 | slimapi init [location] 37 | ``` 38 | 39 | Location defaults to the cwd if not specified. 40 | 41 | If you use a different migration/orm/structure module you'll then have to re-init the appropriate source, such as: 42 | 43 | ``` 44 | slimapi init:db 45 | ``` 46 | 47 | This must be done from the root or your project after the init. 48 | 49 | ###Models 50 | 51 | We can then generate a model, this creates a migration, a simple model class and DI configuration. 52 | 53 | ``` 54 | slimapi generate model 55 | ``` 56 | 57 | Model definitions are a space seperated list of column definitions, of the form `name:type:limit:null:unique`, so 58 | 59 | ``` 60 | slimapi generate model Foo bar:integer baz:string:128:false bazbar:string:128::true 61 | ``` 62 | 63 | Would create a migration of 3 columns, baz would have a character limit and can't be null, bazbar would have a character limit and must be unique. 64 | 65 | ###Controllers 66 | 67 | We can create a controller, this creates a simple controller, route and DI configuration. 68 | 69 | ``` 70 | slimapi generate controller [methods] 71 | ``` 72 | 73 | Methods defaults to index, get, post, put and delete and are empty by default. 74 | The controller name influences how the route is designed. 75 | 76 | ``` 77 | slimapi generate controller Foo index post 78 | ``` 79 | 80 | Would generate a controller named Foo with empty methods index and post. It would also create the GET/POST `/foo` route. 81 | 82 | ``` 83 | slimapi generate controller Foo 84 | ``` 85 | 86 | Would generate a controller named Foo with empty methods index, get, post, put, delete. 87 | It would also create the GET/POST `/foo` routes and the GET/PUT/DELETE `/foo/{id}` routes. 88 | 89 | ###Scaffold 90 | 91 | Scaffolding combines controller and model generation but with added jazz. It configures the controller to receive the model as a constructor param, configures the DI to inject the model to the controller and finally populates the normally empty controller methods with basic CRUD functionality. You can't provide arguments to specify controller methods (it creates them all), but you can supply your model definition. 92 | 93 | ``` 94 | slimapi generate scaffold foo field1:integer field2:string 95 | ``` 96 | 97 | This would generate the Foo controller and appropriate routes, the Foo model/migration with field1/field2 as fillables and any required DI configuration. 98 | -------------------------------------------------------------------------------- /bin/slimapi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 5.6", 7 | "pimple/pimple": "^3.0", 8 | "symfony/console": "^2.7", 9 | "slimphp-api/slim-phinx": "0.1.*", 10 | "slimphp-api/slim-mvc": "0.1.*", 11 | "slim/slim": "^3.0" 12 | }, 13 | "require-dev": { 14 | "phpunit/phpunit": "^5.1", 15 | "mikey179/vfsStream": "1.*", 16 | "satooshi/php-coveralls": "^0.7.0@dev" 17 | }, 18 | "license": "MIT", 19 | "authors": [ 20 | { 21 | "name": "Gabriel Baker", 22 | "email": "me@g403.co" 23 | } 24 | ], 25 | "autoload": { 26 | "psr-4": {"SlimApi\\": "src/"} 27 | }, 28 | "autoload-dev": { 29 | "psr-4": {"SlimApiTest\\": "tests/phpunit/"} 30 | }, 31 | "bin": [ 32 | "bin/slimapi" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "bb508e11c50dc5485378f46210d6e0d5", 8 | "content-hash": "ca263c3c971a58b2815abeff8f431f10", 9 | "packages": [ 10 | { 11 | "name": "container-interop/container-interop", 12 | "version": "1.1.0", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/container-interop/container-interop.git", 16 | "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e", 21 | "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e", 22 | "shasum": "" 23 | }, 24 | "type": "library", 25 | "autoload": { 26 | "psr-4": { 27 | "Interop\\Container\\": "src/Interop/Container/" 28 | } 29 | }, 30 | "notification-url": "https://packagist.org/downloads/", 31 | "license": [ 32 | "MIT" 33 | ], 34 | "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", 35 | "time": "2014-12-30 15:22:37" 36 | }, 37 | { 38 | "name": "nikic/fast-route", 39 | "version": "v0.6.0", 40 | "source": { 41 | "type": "git", 42 | "url": "https://github.com/nikic/FastRoute.git", 43 | "reference": "31fa86924556b80735f98b294a7ffdfb26789f22" 44 | }, 45 | "dist": { 46 | "type": "zip", 47 | "url": "https://api.github.com/repos/nikic/FastRoute/zipball/31fa86924556b80735f98b294a7ffdfb26789f22", 48 | "reference": "31fa86924556b80735f98b294a7ffdfb26789f22", 49 | "shasum": "" 50 | }, 51 | "require": { 52 | "php": ">=5.4.0" 53 | }, 54 | "type": "library", 55 | "autoload": { 56 | "psr-4": { 57 | "FastRoute\\": "src/" 58 | }, 59 | "files": [ 60 | "src/functions.php" 61 | ] 62 | }, 63 | "notification-url": "https://packagist.org/downloads/", 64 | "license": [ 65 | "BSD-3-Clause" 66 | ], 67 | "authors": [ 68 | { 69 | "name": "Nikita Popov", 70 | "email": "nikic@php.net" 71 | } 72 | ], 73 | "description": "Fast request router for PHP", 74 | "keywords": [ 75 | "router", 76 | "routing" 77 | ], 78 | "time": "2015-06-18 19:15:47" 79 | }, 80 | { 81 | "name": "pimple/pimple", 82 | "version": "v3.0.2", 83 | "source": { 84 | "type": "git", 85 | "url": "https://github.com/silexphp/Pimple.git", 86 | "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a" 87 | }, 88 | "dist": { 89 | "type": "zip", 90 | "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a", 91 | "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a", 92 | "shasum": "" 93 | }, 94 | "require": { 95 | "php": ">=5.3.0" 96 | }, 97 | "type": "library", 98 | "extra": { 99 | "branch-alias": { 100 | "dev-master": "3.0.x-dev" 101 | } 102 | }, 103 | "autoload": { 104 | "psr-0": { 105 | "Pimple": "src/" 106 | } 107 | }, 108 | "notification-url": "https://packagist.org/downloads/", 109 | "license": [ 110 | "MIT" 111 | ], 112 | "authors": [ 113 | { 114 | "name": "Fabien Potencier", 115 | "email": "fabien@symfony.com" 116 | } 117 | ], 118 | "description": "Pimple, a simple Dependency Injection Container", 119 | "homepage": "http://pimple.sensiolabs.org", 120 | "keywords": [ 121 | "container", 122 | "dependency injection" 123 | ], 124 | "time": "2015-09-11 15:10:35" 125 | }, 126 | { 127 | "name": "psr/http-message", 128 | "version": "1.0", 129 | "source": { 130 | "type": "git", 131 | "url": "https://github.com/php-fig/http-message.git", 132 | "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" 133 | }, 134 | "dist": { 135 | "type": "zip", 136 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", 137 | "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", 138 | "shasum": "" 139 | }, 140 | "require": { 141 | "php": ">=5.3.0" 142 | }, 143 | "type": "library", 144 | "extra": { 145 | "branch-alias": { 146 | "dev-master": "1.0.x-dev" 147 | } 148 | }, 149 | "autoload": { 150 | "psr-4": { 151 | "Psr\\Http\\Message\\": "src/" 152 | } 153 | }, 154 | "notification-url": "https://packagist.org/downloads/", 155 | "license": [ 156 | "MIT" 157 | ], 158 | "authors": [ 159 | { 160 | "name": "PHP-FIG", 161 | "homepage": "http://www.php-fig.org/" 162 | } 163 | ], 164 | "description": "Common interface for HTTP messages", 165 | "keywords": [ 166 | "http", 167 | "http-message", 168 | "psr", 169 | "psr-7", 170 | "request", 171 | "response" 172 | ], 173 | "time": "2015-05-04 20:22:00" 174 | }, 175 | { 176 | "name": "robmorgan/phinx", 177 | "version": "v0.5.1", 178 | "source": { 179 | "type": "git", 180 | "url": "https://github.com/robmorgan/phinx.git", 181 | "reference": "9e41ae609670645546e08e3907a68b3b8fb60f31" 182 | }, 183 | "dist": { 184 | "type": "zip", 185 | "url": "https://api.github.com/repos/robmorgan/phinx/zipball/9e41ae609670645546e08e3907a68b3b8fb60f31", 186 | "reference": "9e41ae609670645546e08e3907a68b3b8fb60f31", 187 | "shasum": "" 188 | }, 189 | "require": { 190 | "php": ">=5.4", 191 | "symfony/config": "~2.8|~3.0", 192 | "symfony/console": "~2.8|~3.0", 193 | "symfony/yaml": "~2.8|~3.0" 194 | }, 195 | "require-dev": { 196 | "phpunit/phpunit": "^3.7|^4.0|^5.0" 197 | }, 198 | "bin": [ 199 | "bin/phinx" 200 | ], 201 | "type": "library", 202 | "autoload": { 203 | "psr-4": { 204 | "Phinx\\": "src/Phinx" 205 | } 206 | }, 207 | "notification-url": "https://packagist.org/downloads/", 208 | "license": [ 209 | "MIT" 210 | ], 211 | "authors": [ 212 | { 213 | "name": "Rob Morgan", 214 | "email": "robbym@gmail.com", 215 | "homepage": "http://robmorgan.id.au", 216 | "role": "Lead Developer" 217 | }, 218 | { 219 | "name": "Woody Gilk", 220 | "email": "woody.gilk@gmail.com", 221 | "homepage": "http://shadowhand.me", 222 | "role": "Developer" 223 | } 224 | ], 225 | "description": "Phinx makes it ridiculously easy to manage the database migrations for your PHP app.", 226 | "homepage": "https://phinx.org", 227 | "keywords": [ 228 | "database", 229 | "database migrations", 230 | "db", 231 | "migrations", 232 | "phinx" 233 | ], 234 | "time": "2015-12-30 21:16:52" 235 | }, 236 | { 237 | "name": "slim/slim", 238 | "version": "3.1.0", 239 | "source": { 240 | "type": "git", 241 | "url": "https://github.com/slimphp/Slim.git", 242 | "reference": "03b44a4b41896ba42c78bbd5fa172cd79e650496" 243 | }, 244 | "dist": { 245 | "type": "zip", 246 | "url": "https://api.github.com/repos/slimphp/Slim/zipball/03b44a4b41896ba42c78bbd5fa172cd79e650496", 247 | "reference": "03b44a4b41896ba42c78bbd5fa172cd79e650496", 248 | "shasum": "" 249 | }, 250 | "require": { 251 | "container-interop/container-interop": "^1.1", 252 | "nikic/fast-route": "^0.6", 253 | "php": ">=5.5.0", 254 | "pimple/pimple": "^3.0", 255 | "psr/http-message": "^1.0" 256 | }, 257 | "require-dev": { 258 | "phpunit/phpunit": "^4.0", 259 | "squizlabs/php_codesniffer": "^2.5" 260 | }, 261 | "type": "library", 262 | "autoload": { 263 | "psr-4": { 264 | "Slim\\": "Slim" 265 | } 266 | }, 267 | "notification-url": "https://packagist.org/downloads/", 268 | "license": [ 269 | "MIT" 270 | ], 271 | "authors": [ 272 | { 273 | "name": "Rob Allen", 274 | "email": "rob@akrabat.com", 275 | "homepage": "http://akrabat.com" 276 | }, 277 | { 278 | "name": "Josh Lockhart", 279 | "email": "hello@joshlockhart.com", 280 | "homepage": "https://joshlockhart.com" 281 | }, 282 | { 283 | "name": "Gabriel Manricks", 284 | "email": "gmanricks@me.com", 285 | "homepage": "http://gabrielmanricks.com" 286 | }, 287 | { 288 | "name": "Andrew Smith", 289 | "email": "a.smith@silentworks.co.uk", 290 | "homepage": "http://silentworks.co.uk" 291 | } 292 | ], 293 | "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs", 294 | "homepage": "http://slimframework.com", 295 | "keywords": [ 296 | "api", 297 | "framework", 298 | "micro", 299 | "router" 300 | ], 301 | "time": "2016-01-08 15:37:50" 302 | }, 303 | { 304 | "name": "slimphp-api/slim-mvc", 305 | "version": "0.1.4", 306 | "source": { 307 | "type": "git", 308 | "url": "https://github.com/slimphp-api/slim-mvc.git", 309 | "reference": "91fea5c6ccb707faf0719cc4fa59aa2ec36f967f" 310 | }, 311 | "dist": { 312 | "type": "zip", 313 | "url": "https://api.github.com/repos/slimphp-api/slim-mvc/zipball/91fea5c6ccb707faf0719cc4fa59aa2ec36f967f", 314 | "reference": "91fea5c6ccb707faf0719cc4fa59aa2ec36f967f", 315 | "shasum": "" 316 | }, 317 | "require": { 318 | "php": ">5.6", 319 | "slimphp-api/slim-api": "0.1.*" 320 | }, 321 | "require-dev": { 322 | "mikey179/vfsstream": "^1.6", 323 | "phpunit/phpunit": "^5.1", 324 | "satooshi/php-coveralls": "^0.7@dev" 325 | }, 326 | "type": "library", 327 | "autoload": { 328 | "psr-4": { 329 | "SlimApi\\Mvc\\": "src/" 330 | } 331 | }, 332 | "notification-url": "https://packagist.org/downloads/", 333 | "license": [ 334 | "MIT" 335 | ], 336 | "authors": [ 337 | { 338 | "name": "Gabriel Baker", 339 | "email": "me@g403.co" 340 | } 341 | ], 342 | "description": "A module for slim-api for mvc, creating structure, generators for creating controllers/models and scaffold", 343 | "time": "2016-01-12 21:17:20" 344 | }, 345 | { 346 | "name": "slimphp-api/slim-phinx", 347 | "version": "0.1.2", 348 | "source": { 349 | "type": "git", 350 | "url": "https://github.com/slimphp-api/slim-phinx.git", 351 | "reference": "48560f6083e0651389ef0790e59325c751e6574e" 352 | }, 353 | "dist": { 354 | "type": "zip", 355 | "url": "https://api.github.com/repos/slimphp-api/slim-phinx/zipball/48560f6083e0651389ef0790e59325c751e6574e", 356 | "reference": "48560f6083e0651389ef0790e59325c751e6574e", 357 | "shasum": "" 358 | }, 359 | "require": { 360 | "php": ">5.6", 361 | "robmorgan/phinx": "0.*", 362 | "slimphp-api/slim-api": "0.1.*" 363 | }, 364 | "require-dev": { 365 | "mikey179/vfsstream": "1.*", 366 | "phpunit/phpunit": "4.*", 367 | "satooshi/php-coveralls": "^0.7.0@dev" 368 | }, 369 | "type": "library", 370 | "autoload": { 371 | "psr-4": { 372 | "SlimApi\\Phinx\\": "src/" 373 | } 374 | }, 375 | "notification-url": "https://packagist.org/downloads/", 376 | "license": [ 377 | "MIT" 378 | ], 379 | "authors": [ 380 | { 381 | "name": "Gabriel Baker", 382 | "email": "me@g403.co" 383 | } 384 | ], 385 | "description": "A module for slim-api for phinx migration, integrating migrations for slim-api", 386 | "keywords": [ 387 | "api", 388 | "phinx", 389 | "slim", 390 | "slimapi" 391 | ], 392 | "time": "2016-01-12 21:18:13" 393 | }, 394 | { 395 | "name": "symfony/config", 396 | "version": "v3.0.1", 397 | "source": { 398 | "type": "git", 399 | "url": "https://github.com/symfony/config.git", 400 | "reference": "58680a6516a457a6c65044fe33586c4a81fdff01" 401 | }, 402 | "dist": { 403 | "type": "zip", 404 | "url": "https://api.github.com/repos/symfony/config/zipball/58680a6516a457a6c65044fe33586c4a81fdff01", 405 | "reference": "58680a6516a457a6c65044fe33586c4a81fdff01", 406 | "shasum": "" 407 | }, 408 | "require": { 409 | "php": ">=5.5.9", 410 | "symfony/filesystem": "~2.8|~3.0" 411 | }, 412 | "type": "library", 413 | "extra": { 414 | "branch-alias": { 415 | "dev-master": "3.0-dev" 416 | } 417 | }, 418 | "autoload": { 419 | "psr-4": { 420 | "Symfony\\Component\\Config\\": "" 421 | }, 422 | "exclude-from-classmap": [ 423 | "/Tests/" 424 | ] 425 | }, 426 | "notification-url": "https://packagist.org/downloads/", 427 | "license": [ 428 | "MIT" 429 | ], 430 | "authors": [ 431 | { 432 | "name": "Fabien Potencier", 433 | "email": "fabien@symfony.com" 434 | }, 435 | { 436 | "name": "Symfony Community", 437 | "homepage": "https://symfony.com/contributors" 438 | } 439 | ], 440 | "description": "Symfony Config Component", 441 | "homepage": "https://symfony.com", 442 | "time": "2015-12-26 13:39:53" 443 | }, 444 | { 445 | "name": "symfony/console", 446 | "version": "v2.8.1", 447 | "source": { 448 | "type": "git", 449 | "url": "https://github.com/symfony/console.git", 450 | "reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a" 451 | }, 452 | "dist": { 453 | "type": "zip", 454 | "url": "https://api.github.com/repos/symfony/console/zipball/2e06a5ccb19dcf9b89f1c6a677a39a8df773635a", 455 | "reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a", 456 | "shasum": "" 457 | }, 458 | "require": { 459 | "php": ">=5.3.9", 460 | "symfony/polyfill-mbstring": "~1.0" 461 | }, 462 | "require-dev": { 463 | "psr/log": "~1.0", 464 | "symfony/event-dispatcher": "~2.1|~3.0.0", 465 | "symfony/process": "~2.1|~3.0.0" 466 | }, 467 | "suggest": { 468 | "psr/log": "For using the console logger", 469 | "symfony/event-dispatcher": "", 470 | "symfony/process": "" 471 | }, 472 | "type": "library", 473 | "extra": { 474 | "branch-alias": { 475 | "dev-master": "2.8-dev" 476 | } 477 | }, 478 | "autoload": { 479 | "psr-4": { 480 | "Symfony\\Component\\Console\\": "" 481 | }, 482 | "exclude-from-classmap": [ 483 | "/Tests/" 484 | ] 485 | }, 486 | "notification-url": "https://packagist.org/downloads/", 487 | "license": [ 488 | "MIT" 489 | ], 490 | "authors": [ 491 | { 492 | "name": "Fabien Potencier", 493 | "email": "fabien@symfony.com" 494 | }, 495 | { 496 | "name": "Symfony Community", 497 | "homepage": "https://symfony.com/contributors" 498 | } 499 | ], 500 | "description": "Symfony Console Component", 501 | "homepage": "https://symfony.com", 502 | "time": "2015-12-22 10:25:57" 503 | }, 504 | { 505 | "name": "symfony/filesystem", 506 | "version": "v3.0.1", 507 | "source": { 508 | "type": "git", 509 | "url": "https://github.com/symfony/filesystem.git", 510 | "reference": "c2e59d11dccd135dc8f00ee97f34fe1de842e70c" 511 | }, 512 | "dist": { 513 | "type": "zip", 514 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/c2e59d11dccd135dc8f00ee97f34fe1de842e70c", 515 | "reference": "c2e59d11dccd135dc8f00ee97f34fe1de842e70c", 516 | "shasum": "" 517 | }, 518 | "require": { 519 | "php": ">=5.5.9" 520 | }, 521 | "type": "library", 522 | "extra": { 523 | "branch-alias": { 524 | "dev-master": "3.0-dev" 525 | } 526 | }, 527 | "autoload": { 528 | "psr-4": { 529 | "Symfony\\Component\\Filesystem\\": "" 530 | }, 531 | "exclude-from-classmap": [ 532 | "/Tests/" 533 | ] 534 | }, 535 | "notification-url": "https://packagist.org/downloads/", 536 | "license": [ 537 | "MIT" 538 | ], 539 | "authors": [ 540 | { 541 | "name": "Fabien Potencier", 542 | "email": "fabien@symfony.com" 543 | }, 544 | { 545 | "name": "Symfony Community", 546 | "homepage": "https://symfony.com/contributors" 547 | } 548 | ], 549 | "description": "Symfony Filesystem Component", 550 | "homepage": "https://symfony.com", 551 | "time": "2015-12-22 10:39:06" 552 | }, 553 | { 554 | "name": "symfony/polyfill-mbstring", 555 | "version": "v1.0.1", 556 | "source": { 557 | "type": "git", 558 | "url": "https://github.com/symfony/polyfill-mbstring.git", 559 | "reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25" 560 | }, 561 | "dist": { 562 | "type": "zip", 563 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/49ff736bd5d41f45240cec77b44967d76e0c3d25", 564 | "reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25", 565 | "shasum": "" 566 | }, 567 | "require": { 568 | "php": ">=5.3.3" 569 | }, 570 | "suggest": { 571 | "ext-mbstring": "For best performance" 572 | }, 573 | "type": "library", 574 | "extra": { 575 | "branch-alias": { 576 | "dev-master": "1.0-dev" 577 | } 578 | }, 579 | "autoload": { 580 | "psr-4": { 581 | "Symfony\\Polyfill\\Mbstring\\": "" 582 | }, 583 | "files": [ 584 | "bootstrap.php" 585 | ] 586 | }, 587 | "notification-url": "https://packagist.org/downloads/", 588 | "license": [ 589 | "MIT" 590 | ], 591 | "authors": [ 592 | { 593 | "name": "Nicolas Grekas", 594 | "email": "p@tchwork.com" 595 | }, 596 | { 597 | "name": "Symfony Community", 598 | "homepage": "https://symfony.com/contributors" 599 | } 600 | ], 601 | "description": "Symfony polyfill for the Mbstring extension", 602 | "homepage": "https://symfony.com", 603 | "keywords": [ 604 | "compatibility", 605 | "mbstring", 606 | "polyfill", 607 | "portable", 608 | "shim" 609 | ], 610 | "time": "2015-11-20 09:19:13" 611 | }, 612 | { 613 | "name": "symfony/yaml", 614 | "version": "v3.0.1", 615 | "source": { 616 | "type": "git", 617 | "url": "https://github.com/symfony/yaml.git", 618 | "reference": "3df409958a646dad2bc5046c3fb671ee24a1a691" 619 | }, 620 | "dist": { 621 | "type": "zip", 622 | "url": "https://api.github.com/repos/symfony/yaml/zipball/3df409958a646dad2bc5046c3fb671ee24a1a691", 623 | "reference": "3df409958a646dad2bc5046c3fb671ee24a1a691", 624 | "shasum": "" 625 | }, 626 | "require": { 627 | "php": ">=5.5.9" 628 | }, 629 | "type": "library", 630 | "extra": { 631 | "branch-alias": { 632 | "dev-master": "3.0-dev" 633 | } 634 | }, 635 | "autoload": { 636 | "psr-4": { 637 | "Symfony\\Component\\Yaml\\": "" 638 | }, 639 | "exclude-from-classmap": [ 640 | "/Tests/" 641 | ] 642 | }, 643 | "notification-url": "https://packagist.org/downloads/", 644 | "license": [ 645 | "MIT" 646 | ], 647 | "authors": [ 648 | { 649 | "name": "Fabien Potencier", 650 | "email": "fabien@symfony.com" 651 | }, 652 | { 653 | "name": "Symfony Community", 654 | "homepage": "https://symfony.com/contributors" 655 | } 656 | ], 657 | "description": "Symfony Yaml Component", 658 | "homepage": "https://symfony.com", 659 | "time": "2015-12-26 13:39:53" 660 | } 661 | ], 662 | "packages-dev": [ 663 | { 664 | "name": "doctrine/instantiator", 665 | "version": "1.0.5", 666 | "source": { 667 | "type": "git", 668 | "url": "https://github.com/doctrine/instantiator.git", 669 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 670 | }, 671 | "dist": { 672 | "type": "zip", 673 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 674 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 675 | "shasum": "" 676 | }, 677 | "require": { 678 | "php": ">=5.3,<8.0-DEV" 679 | }, 680 | "require-dev": { 681 | "athletic/athletic": "~0.1.8", 682 | "ext-pdo": "*", 683 | "ext-phar": "*", 684 | "phpunit/phpunit": "~4.0", 685 | "squizlabs/php_codesniffer": "~2.0" 686 | }, 687 | "type": "library", 688 | "extra": { 689 | "branch-alias": { 690 | "dev-master": "1.0.x-dev" 691 | } 692 | }, 693 | "autoload": { 694 | "psr-4": { 695 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 696 | } 697 | }, 698 | "notification-url": "https://packagist.org/downloads/", 699 | "license": [ 700 | "MIT" 701 | ], 702 | "authors": [ 703 | { 704 | "name": "Marco Pivetta", 705 | "email": "ocramius@gmail.com", 706 | "homepage": "http://ocramius.github.com/" 707 | } 708 | ], 709 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 710 | "homepage": "https://github.com/doctrine/instantiator", 711 | "keywords": [ 712 | "constructor", 713 | "instantiate" 714 | ], 715 | "time": "2015-06-14 21:17:01" 716 | }, 717 | { 718 | "name": "guzzle/guzzle", 719 | "version": "v3.9.3", 720 | "source": { 721 | "type": "git", 722 | "url": "https://github.com/guzzle/guzzle3.git", 723 | "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" 724 | }, 725 | "dist": { 726 | "type": "zip", 727 | "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", 728 | "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", 729 | "shasum": "" 730 | }, 731 | "require": { 732 | "ext-curl": "*", 733 | "php": ">=5.3.3", 734 | "symfony/event-dispatcher": "~2.1" 735 | }, 736 | "replace": { 737 | "guzzle/batch": "self.version", 738 | "guzzle/cache": "self.version", 739 | "guzzle/common": "self.version", 740 | "guzzle/http": "self.version", 741 | "guzzle/inflection": "self.version", 742 | "guzzle/iterator": "self.version", 743 | "guzzle/log": "self.version", 744 | "guzzle/parser": "self.version", 745 | "guzzle/plugin": "self.version", 746 | "guzzle/plugin-async": "self.version", 747 | "guzzle/plugin-backoff": "self.version", 748 | "guzzle/plugin-cache": "self.version", 749 | "guzzle/plugin-cookie": "self.version", 750 | "guzzle/plugin-curlauth": "self.version", 751 | "guzzle/plugin-error-response": "self.version", 752 | "guzzle/plugin-history": "self.version", 753 | "guzzle/plugin-log": "self.version", 754 | "guzzle/plugin-md5": "self.version", 755 | "guzzle/plugin-mock": "self.version", 756 | "guzzle/plugin-oauth": "self.version", 757 | "guzzle/service": "self.version", 758 | "guzzle/stream": "self.version" 759 | }, 760 | "require-dev": { 761 | "doctrine/cache": "~1.3", 762 | "monolog/monolog": "~1.0", 763 | "phpunit/phpunit": "3.7.*", 764 | "psr/log": "~1.0", 765 | "symfony/class-loader": "~2.1", 766 | "zendframework/zend-cache": "2.*,<2.3", 767 | "zendframework/zend-log": "2.*,<2.3" 768 | }, 769 | "suggest": { 770 | "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." 771 | }, 772 | "type": "library", 773 | "extra": { 774 | "branch-alias": { 775 | "dev-master": "3.9-dev" 776 | } 777 | }, 778 | "autoload": { 779 | "psr-0": { 780 | "Guzzle": "src/", 781 | "Guzzle\\Tests": "tests/" 782 | } 783 | }, 784 | "notification-url": "https://packagist.org/downloads/", 785 | "license": [ 786 | "MIT" 787 | ], 788 | "authors": [ 789 | { 790 | "name": "Michael Dowling", 791 | "email": "mtdowling@gmail.com", 792 | "homepage": "https://github.com/mtdowling" 793 | }, 794 | { 795 | "name": "Guzzle Community", 796 | "homepage": "https://github.com/guzzle/guzzle/contributors" 797 | } 798 | ], 799 | "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", 800 | "homepage": "http://guzzlephp.org/", 801 | "keywords": [ 802 | "client", 803 | "curl", 804 | "framework", 805 | "http", 806 | "http client", 807 | "rest", 808 | "web service" 809 | ], 810 | "time": "2015-03-18 18:23:50" 811 | }, 812 | { 813 | "name": "mikey179/vfsStream", 814 | "version": "v1.6.1", 815 | "source": { 816 | "type": "git", 817 | "url": "https://github.com/mikey179/vfsStream.git", 818 | "reference": "f4aabeb1976f96343ad1253c8d60ad40307e409a" 819 | }, 820 | "dist": { 821 | "type": "zip", 822 | "url": "https://api.github.com/repos/mikey179/vfsStream/zipball/f4aabeb1976f96343ad1253c8d60ad40307e409a", 823 | "reference": "f4aabeb1976f96343ad1253c8d60ad40307e409a", 824 | "shasum": "" 825 | }, 826 | "require": { 827 | "php": ">=5.3.0" 828 | }, 829 | "require-dev": { 830 | "phpunit/phpunit": "~4.5" 831 | }, 832 | "type": "library", 833 | "extra": { 834 | "branch-alias": { 835 | "dev-master": "1.6.x-dev" 836 | } 837 | }, 838 | "autoload": { 839 | "psr-0": { 840 | "org\\bovigo\\vfs\\": "src/main/php" 841 | } 842 | }, 843 | "notification-url": "https://packagist.org/downloads/", 844 | "license": [ 845 | "BSD-3-Clause" 846 | ], 847 | "authors": [ 848 | { 849 | "name": "Frank Kleine", 850 | "homepage": "http://frankkleine.de/", 851 | "role": "Developer" 852 | } 853 | ], 854 | "description": "Virtual file system to mock the real file system in unit tests.", 855 | "homepage": "http://vfs.bovigo.org/", 856 | "time": "2015-12-04 12:02:33" 857 | }, 858 | { 859 | "name": "myclabs/deep-copy", 860 | "version": "1.5.0", 861 | "source": { 862 | "type": "git", 863 | "url": "https://github.com/myclabs/DeepCopy.git", 864 | "reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc" 865 | }, 866 | "dist": { 867 | "type": "zip", 868 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e3abefcd7f106677fd352cd7c187d6c969aa9ddc", 869 | "reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc", 870 | "shasum": "" 871 | }, 872 | "require": { 873 | "php": ">=5.4.0" 874 | }, 875 | "require-dev": { 876 | "doctrine/collections": "1.*", 877 | "phpunit/phpunit": "~4.1" 878 | }, 879 | "type": "library", 880 | "autoload": { 881 | "psr-4": { 882 | "DeepCopy\\": "src/DeepCopy/" 883 | } 884 | }, 885 | "notification-url": "https://packagist.org/downloads/", 886 | "license": [ 887 | "MIT" 888 | ], 889 | "description": "Create deep copies (clones) of your objects", 890 | "homepage": "https://github.com/myclabs/DeepCopy", 891 | "keywords": [ 892 | "clone", 893 | "copy", 894 | "duplicate", 895 | "object", 896 | "object graph" 897 | ], 898 | "time": "2015-11-07 22:20:37" 899 | }, 900 | { 901 | "name": "phpdocumentor/reflection-docblock", 902 | "version": "2.0.4", 903 | "source": { 904 | "type": "git", 905 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 906 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" 907 | }, 908 | "dist": { 909 | "type": "zip", 910 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", 911 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", 912 | "shasum": "" 913 | }, 914 | "require": { 915 | "php": ">=5.3.3" 916 | }, 917 | "require-dev": { 918 | "phpunit/phpunit": "~4.0" 919 | }, 920 | "suggest": { 921 | "dflydev/markdown": "~1.0", 922 | "erusev/parsedown": "~1.0" 923 | }, 924 | "type": "library", 925 | "extra": { 926 | "branch-alias": { 927 | "dev-master": "2.0.x-dev" 928 | } 929 | }, 930 | "autoload": { 931 | "psr-0": { 932 | "phpDocumentor": [ 933 | "src/" 934 | ] 935 | } 936 | }, 937 | "notification-url": "https://packagist.org/downloads/", 938 | "license": [ 939 | "MIT" 940 | ], 941 | "authors": [ 942 | { 943 | "name": "Mike van Riel", 944 | "email": "mike.vanriel@naenius.com" 945 | } 946 | ], 947 | "time": "2015-02-03 12:10:50" 948 | }, 949 | { 950 | "name": "phpspec/prophecy", 951 | "version": "v1.5.0", 952 | "source": { 953 | "type": "git", 954 | "url": "https://github.com/phpspec/prophecy.git", 955 | "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" 956 | }, 957 | "dist": { 958 | "type": "zip", 959 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", 960 | "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", 961 | "shasum": "" 962 | }, 963 | "require": { 964 | "doctrine/instantiator": "^1.0.2", 965 | "phpdocumentor/reflection-docblock": "~2.0", 966 | "sebastian/comparator": "~1.1" 967 | }, 968 | "require-dev": { 969 | "phpspec/phpspec": "~2.0" 970 | }, 971 | "type": "library", 972 | "extra": { 973 | "branch-alias": { 974 | "dev-master": "1.4.x-dev" 975 | } 976 | }, 977 | "autoload": { 978 | "psr-0": { 979 | "Prophecy\\": "src/" 980 | } 981 | }, 982 | "notification-url": "https://packagist.org/downloads/", 983 | "license": [ 984 | "MIT" 985 | ], 986 | "authors": [ 987 | { 988 | "name": "Konstantin Kudryashov", 989 | "email": "ever.zet@gmail.com", 990 | "homepage": "http://everzet.com" 991 | }, 992 | { 993 | "name": "Marcello Duarte", 994 | "email": "marcello.duarte@gmail.com" 995 | } 996 | ], 997 | "description": "Highly opinionated mocking framework for PHP 5.3+", 998 | "homepage": "https://github.com/phpspec/prophecy", 999 | "keywords": [ 1000 | "Double", 1001 | "Dummy", 1002 | "fake", 1003 | "mock", 1004 | "spy", 1005 | "stub" 1006 | ], 1007 | "time": "2015-08-13 10:07:40" 1008 | }, 1009 | { 1010 | "name": "phpunit/php-code-coverage", 1011 | "version": "3.1.0", 1012 | "source": { 1013 | "type": "git", 1014 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 1015 | "reference": "64d40a593fc31a8abf4ce3d200147ddf8ca64e52" 1016 | }, 1017 | "dist": { 1018 | "type": "zip", 1019 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/64d40a593fc31a8abf4ce3d200147ddf8ca64e52", 1020 | "reference": "64d40a593fc31a8abf4ce3d200147ddf8ca64e52", 1021 | "shasum": "" 1022 | }, 1023 | "require": { 1024 | "php": ">=5.6", 1025 | "phpunit/php-file-iterator": "~1.3", 1026 | "phpunit/php-text-template": "~1.2", 1027 | "phpunit/php-token-stream": "~1.3", 1028 | "sebastian/environment": "^1.3.2", 1029 | "sebastian/version": "~1.0" 1030 | }, 1031 | "require-dev": { 1032 | "ext-xdebug": ">=2.1.4", 1033 | "phpunit/phpunit": "~5" 1034 | }, 1035 | "suggest": { 1036 | "ext-dom": "*", 1037 | "ext-xdebug": ">=2.2.1", 1038 | "ext-xmlwriter": "*" 1039 | }, 1040 | "type": "library", 1041 | "extra": { 1042 | "branch-alias": { 1043 | "dev-master": "3.1.x-dev" 1044 | } 1045 | }, 1046 | "autoload": { 1047 | "classmap": [ 1048 | "src/" 1049 | ] 1050 | }, 1051 | "notification-url": "https://packagist.org/downloads/", 1052 | "license": [ 1053 | "BSD-3-Clause" 1054 | ], 1055 | "authors": [ 1056 | { 1057 | "name": "Sebastian Bergmann", 1058 | "email": "sb@sebastian-bergmann.de", 1059 | "role": "lead" 1060 | } 1061 | ], 1062 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 1063 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 1064 | "keywords": [ 1065 | "coverage", 1066 | "testing", 1067 | "xunit" 1068 | ], 1069 | "time": "2016-01-11 10:05:34" 1070 | }, 1071 | { 1072 | "name": "phpunit/php-file-iterator", 1073 | "version": "1.4.1", 1074 | "source": { 1075 | "type": "git", 1076 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 1077 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" 1078 | }, 1079 | "dist": { 1080 | "type": "zip", 1081 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 1082 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 1083 | "shasum": "" 1084 | }, 1085 | "require": { 1086 | "php": ">=5.3.3" 1087 | }, 1088 | "type": "library", 1089 | "extra": { 1090 | "branch-alias": { 1091 | "dev-master": "1.4.x-dev" 1092 | } 1093 | }, 1094 | "autoload": { 1095 | "classmap": [ 1096 | "src/" 1097 | ] 1098 | }, 1099 | "notification-url": "https://packagist.org/downloads/", 1100 | "license": [ 1101 | "BSD-3-Clause" 1102 | ], 1103 | "authors": [ 1104 | { 1105 | "name": "Sebastian Bergmann", 1106 | "email": "sb@sebastian-bergmann.de", 1107 | "role": "lead" 1108 | } 1109 | ], 1110 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 1111 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 1112 | "keywords": [ 1113 | "filesystem", 1114 | "iterator" 1115 | ], 1116 | "time": "2015-06-21 13:08:43" 1117 | }, 1118 | { 1119 | "name": "phpunit/php-text-template", 1120 | "version": "1.2.1", 1121 | "source": { 1122 | "type": "git", 1123 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 1124 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 1125 | }, 1126 | "dist": { 1127 | "type": "zip", 1128 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1129 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 1130 | "shasum": "" 1131 | }, 1132 | "require": { 1133 | "php": ">=5.3.3" 1134 | }, 1135 | "type": "library", 1136 | "autoload": { 1137 | "classmap": [ 1138 | "src/" 1139 | ] 1140 | }, 1141 | "notification-url": "https://packagist.org/downloads/", 1142 | "license": [ 1143 | "BSD-3-Clause" 1144 | ], 1145 | "authors": [ 1146 | { 1147 | "name": "Sebastian Bergmann", 1148 | "email": "sebastian@phpunit.de", 1149 | "role": "lead" 1150 | } 1151 | ], 1152 | "description": "Simple template engine.", 1153 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 1154 | "keywords": [ 1155 | "template" 1156 | ], 1157 | "time": "2015-06-21 13:50:34" 1158 | }, 1159 | { 1160 | "name": "phpunit/php-timer", 1161 | "version": "1.0.7", 1162 | "source": { 1163 | "type": "git", 1164 | "url": "https://github.com/sebastianbergmann/php-timer.git", 1165 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" 1166 | }, 1167 | "dist": { 1168 | "type": "zip", 1169 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", 1170 | "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", 1171 | "shasum": "" 1172 | }, 1173 | "require": { 1174 | "php": ">=5.3.3" 1175 | }, 1176 | "type": "library", 1177 | "autoload": { 1178 | "classmap": [ 1179 | "src/" 1180 | ] 1181 | }, 1182 | "notification-url": "https://packagist.org/downloads/", 1183 | "license": [ 1184 | "BSD-3-Clause" 1185 | ], 1186 | "authors": [ 1187 | { 1188 | "name": "Sebastian Bergmann", 1189 | "email": "sb@sebastian-bergmann.de", 1190 | "role": "lead" 1191 | } 1192 | ], 1193 | "description": "Utility class for timing", 1194 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 1195 | "keywords": [ 1196 | "timer" 1197 | ], 1198 | "time": "2015-06-21 08:01:12" 1199 | }, 1200 | { 1201 | "name": "phpunit/php-token-stream", 1202 | "version": "1.4.8", 1203 | "source": { 1204 | "type": "git", 1205 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 1206 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" 1207 | }, 1208 | "dist": { 1209 | "type": "zip", 1210 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 1211 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 1212 | "shasum": "" 1213 | }, 1214 | "require": { 1215 | "ext-tokenizer": "*", 1216 | "php": ">=5.3.3" 1217 | }, 1218 | "require-dev": { 1219 | "phpunit/phpunit": "~4.2" 1220 | }, 1221 | "type": "library", 1222 | "extra": { 1223 | "branch-alias": { 1224 | "dev-master": "1.4-dev" 1225 | } 1226 | }, 1227 | "autoload": { 1228 | "classmap": [ 1229 | "src/" 1230 | ] 1231 | }, 1232 | "notification-url": "https://packagist.org/downloads/", 1233 | "license": [ 1234 | "BSD-3-Clause" 1235 | ], 1236 | "authors": [ 1237 | { 1238 | "name": "Sebastian Bergmann", 1239 | "email": "sebastian@phpunit.de" 1240 | } 1241 | ], 1242 | "description": "Wrapper around PHP's tokenizer extension.", 1243 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 1244 | "keywords": [ 1245 | "tokenizer" 1246 | ], 1247 | "time": "2015-09-15 10:49:45" 1248 | }, 1249 | { 1250 | "name": "phpunit/phpunit", 1251 | "version": "5.1.4", 1252 | "source": { 1253 | "type": "git", 1254 | "url": "https://github.com/sebastianbergmann/phpunit.git", 1255 | "reference": "676c25c4ac563869572c878fdaf3db21587f5f3b" 1256 | }, 1257 | "dist": { 1258 | "type": "zip", 1259 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/676c25c4ac563869572c878fdaf3db21587f5f3b", 1260 | "reference": "676c25c4ac563869572c878fdaf3db21587f5f3b", 1261 | "shasum": "" 1262 | }, 1263 | "require": { 1264 | "ext-dom": "*", 1265 | "ext-json": "*", 1266 | "ext-pcre": "*", 1267 | "ext-reflection": "*", 1268 | "ext-spl": "*", 1269 | "myclabs/deep-copy": "~1.3", 1270 | "php": ">=5.6", 1271 | "phpspec/prophecy": "^1.3.1", 1272 | "phpunit/php-code-coverage": "~3.0", 1273 | "phpunit/php-file-iterator": "~1.4", 1274 | "phpunit/php-text-template": "~1.2", 1275 | "phpunit/php-timer": ">=1.0.6", 1276 | "phpunit/phpunit-mock-objects": ">=3.0.5", 1277 | "sebastian/comparator": "~1.1", 1278 | "sebastian/diff": "~1.2", 1279 | "sebastian/environment": "~1.3", 1280 | "sebastian/exporter": "~1.2", 1281 | "sebastian/global-state": "~1.0", 1282 | "sebastian/resource-operations": "~1.0", 1283 | "sebastian/version": "~1.0", 1284 | "symfony/yaml": "~2.1|~3.0" 1285 | }, 1286 | "suggest": { 1287 | "phpunit/php-invoker": "~1.1" 1288 | }, 1289 | "bin": [ 1290 | "phpunit" 1291 | ], 1292 | "type": "library", 1293 | "extra": { 1294 | "branch-alias": { 1295 | "dev-master": "5.1.x-dev" 1296 | } 1297 | }, 1298 | "autoload": { 1299 | "classmap": [ 1300 | "src/" 1301 | ] 1302 | }, 1303 | "notification-url": "https://packagist.org/downloads/", 1304 | "license": [ 1305 | "BSD-3-Clause" 1306 | ], 1307 | "authors": [ 1308 | { 1309 | "name": "Sebastian Bergmann", 1310 | "email": "sebastian@phpunit.de", 1311 | "role": "lead" 1312 | } 1313 | ], 1314 | "description": "The PHP Unit Testing framework.", 1315 | "homepage": "https://phpunit.de/", 1316 | "keywords": [ 1317 | "phpunit", 1318 | "testing", 1319 | "xunit" 1320 | ], 1321 | "time": "2016-01-11 10:11:10" 1322 | }, 1323 | { 1324 | "name": "phpunit/phpunit-mock-objects", 1325 | "version": "3.0.6", 1326 | "source": { 1327 | "type": "git", 1328 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 1329 | "reference": "49bc700750196c04dd6bc2c4c99cb632b893836b" 1330 | }, 1331 | "dist": { 1332 | "type": "zip", 1333 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/49bc700750196c04dd6bc2c4c99cb632b893836b", 1334 | "reference": "49bc700750196c04dd6bc2c4c99cb632b893836b", 1335 | "shasum": "" 1336 | }, 1337 | "require": { 1338 | "doctrine/instantiator": "^1.0.2", 1339 | "php": ">=5.6", 1340 | "phpunit/php-text-template": "~1.2", 1341 | "sebastian/exporter": "~1.2" 1342 | }, 1343 | "require-dev": { 1344 | "phpunit/phpunit": "~5" 1345 | }, 1346 | "suggest": { 1347 | "ext-soap": "*" 1348 | }, 1349 | "type": "library", 1350 | "extra": { 1351 | "branch-alias": { 1352 | "dev-master": "3.0.x-dev" 1353 | } 1354 | }, 1355 | "autoload": { 1356 | "classmap": [ 1357 | "src/" 1358 | ] 1359 | }, 1360 | "notification-url": "https://packagist.org/downloads/", 1361 | "license": [ 1362 | "BSD-3-Clause" 1363 | ], 1364 | "authors": [ 1365 | { 1366 | "name": "Sebastian Bergmann", 1367 | "email": "sb@sebastian-bergmann.de", 1368 | "role": "lead" 1369 | } 1370 | ], 1371 | "description": "Mock Object library for PHPUnit", 1372 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1373 | "keywords": [ 1374 | "mock", 1375 | "xunit" 1376 | ], 1377 | "time": "2015-12-08 08:47:06" 1378 | }, 1379 | { 1380 | "name": "psr/log", 1381 | "version": "1.0.0", 1382 | "source": { 1383 | "type": "git", 1384 | "url": "https://github.com/php-fig/log.git", 1385 | "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" 1386 | }, 1387 | "dist": { 1388 | "type": "zip", 1389 | "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", 1390 | "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", 1391 | "shasum": "" 1392 | }, 1393 | "type": "library", 1394 | "autoload": { 1395 | "psr-0": { 1396 | "Psr\\Log\\": "" 1397 | } 1398 | }, 1399 | "notification-url": "https://packagist.org/downloads/", 1400 | "license": [ 1401 | "MIT" 1402 | ], 1403 | "authors": [ 1404 | { 1405 | "name": "PHP-FIG", 1406 | "homepage": "http://www.php-fig.org/" 1407 | } 1408 | ], 1409 | "description": "Common interface for logging libraries", 1410 | "keywords": [ 1411 | "log", 1412 | "psr", 1413 | "psr-3" 1414 | ], 1415 | "time": "2012-12-21 11:40:51" 1416 | }, 1417 | { 1418 | "name": "satooshi/php-coveralls", 1419 | "version": "v0.7.1", 1420 | "source": { 1421 | "type": "git", 1422 | "url": "https://github.com/satooshi/php-coveralls.git", 1423 | "reference": "01793ce60f1e259592ac3cb7c3fc183209800127" 1424 | }, 1425 | "dist": { 1426 | "type": "zip", 1427 | "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/01793ce60f1e259592ac3cb7c3fc183209800127", 1428 | "reference": "01793ce60f1e259592ac3cb7c3fc183209800127", 1429 | "shasum": "" 1430 | }, 1431 | "require": { 1432 | "ext-json": "*", 1433 | "ext-simplexml": "*", 1434 | "guzzle/guzzle": "^2.8|^3.0", 1435 | "php": ">=5.3.3", 1436 | "psr/log": "^1.0", 1437 | "symfony/config": "^2.4|^3.0", 1438 | "symfony/console": "^2.1|^3.0", 1439 | "symfony/stopwatch": "^2.2|^3.0", 1440 | "symfony/yaml": "^2.1|^3.0" 1441 | }, 1442 | "suggest": { 1443 | "symfony/http-kernel": "Allows Symfony integration" 1444 | }, 1445 | "bin": [ 1446 | "bin/coveralls" 1447 | ], 1448 | "type": "library", 1449 | "extra": { 1450 | "branch-alias": { 1451 | "dev-master": "0.8-dev" 1452 | } 1453 | }, 1454 | "autoload": { 1455 | "psr-4": { 1456 | "Satooshi\\": "src/Satooshi/" 1457 | } 1458 | }, 1459 | "notification-url": "https://packagist.org/downloads/", 1460 | "license": [ 1461 | "MIT" 1462 | ], 1463 | "authors": [ 1464 | { 1465 | "name": "Kitamura Satoshi", 1466 | "email": "with.no.parachute@gmail.com", 1467 | "homepage": "https://www.facebook.com/satooshi.jp" 1468 | } 1469 | ], 1470 | "description": "PHP client library for Coveralls API", 1471 | "homepage": "https://github.com/satooshi/php-coveralls", 1472 | "keywords": [ 1473 | "ci", 1474 | "coverage", 1475 | "github", 1476 | "test" 1477 | ], 1478 | "time": "2015-12-17 18:04:18" 1479 | }, 1480 | { 1481 | "name": "sebastian/comparator", 1482 | "version": "1.2.0", 1483 | "source": { 1484 | "type": "git", 1485 | "url": "https://github.com/sebastianbergmann/comparator.git", 1486 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" 1487 | }, 1488 | "dist": { 1489 | "type": "zip", 1490 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", 1491 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", 1492 | "shasum": "" 1493 | }, 1494 | "require": { 1495 | "php": ">=5.3.3", 1496 | "sebastian/diff": "~1.2", 1497 | "sebastian/exporter": "~1.2" 1498 | }, 1499 | "require-dev": { 1500 | "phpunit/phpunit": "~4.4" 1501 | }, 1502 | "type": "library", 1503 | "extra": { 1504 | "branch-alias": { 1505 | "dev-master": "1.2.x-dev" 1506 | } 1507 | }, 1508 | "autoload": { 1509 | "classmap": [ 1510 | "src/" 1511 | ] 1512 | }, 1513 | "notification-url": "https://packagist.org/downloads/", 1514 | "license": [ 1515 | "BSD-3-Clause" 1516 | ], 1517 | "authors": [ 1518 | { 1519 | "name": "Jeff Welch", 1520 | "email": "whatthejeff@gmail.com" 1521 | }, 1522 | { 1523 | "name": "Volker Dusch", 1524 | "email": "github@wallbash.com" 1525 | }, 1526 | { 1527 | "name": "Bernhard Schussek", 1528 | "email": "bschussek@2bepublished.at" 1529 | }, 1530 | { 1531 | "name": "Sebastian Bergmann", 1532 | "email": "sebastian@phpunit.de" 1533 | } 1534 | ], 1535 | "description": "Provides the functionality to compare PHP values for equality", 1536 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1537 | "keywords": [ 1538 | "comparator", 1539 | "compare", 1540 | "equality" 1541 | ], 1542 | "time": "2015-07-26 15:48:44" 1543 | }, 1544 | { 1545 | "name": "sebastian/diff", 1546 | "version": "1.4.1", 1547 | "source": { 1548 | "type": "git", 1549 | "url": "https://github.com/sebastianbergmann/diff.git", 1550 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" 1551 | }, 1552 | "dist": { 1553 | "type": "zip", 1554 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", 1555 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", 1556 | "shasum": "" 1557 | }, 1558 | "require": { 1559 | "php": ">=5.3.3" 1560 | }, 1561 | "require-dev": { 1562 | "phpunit/phpunit": "~4.8" 1563 | }, 1564 | "type": "library", 1565 | "extra": { 1566 | "branch-alias": { 1567 | "dev-master": "1.4-dev" 1568 | } 1569 | }, 1570 | "autoload": { 1571 | "classmap": [ 1572 | "src/" 1573 | ] 1574 | }, 1575 | "notification-url": "https://packagist.org/downloads/", 1576 | "license": [ 1577 | "BSD-3-Clause" 1578 | ], 1579 | "authors": [ 1580 | { 1581 | "name": "Kore Nordmann", 1582 | "email": "mail@kore-nordmann.de" 1583 | }, 1584 | { 1585 | "name": "Sebastian Bergmann", 1586 | "email": "sebastian@phpunit.de" 1587 | } 1588 | ], 1589 | "description": "Diff implementation", 1590 | "homepage": "https://github.com/sebastianbergmann/diff", 1591 | "keywords": [ 1592 | "diff" 1593 | ], 1594 | "time": "2015-12-08 07:14:41" 1595 | }, 1596 | { 1597 | "name": "sebastian/environment", 1598 | "version": "1.3.3", 1599 | "source": { 1600 | "type": "git", 1601 | "url": "https://github.com/sebastianbergmann/environment.git", 1602 | "reference": "6e7133793a8e5a5714a551a8324337374be209df" 1603 | }, 1604 | "dist": { 1605 | "type": "zip", 1606 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df", 1607 | "reference": "6e7133793a8e5a5714a551a8324337374be209df", 1608 | "shasum": "" 1609 | }, 1610 | "require": { 1611 | "php": ">=5.3.3" 1612 | }, 1613 | "require-dev": { 1614 | "phpunit/phpunit": "~4.4" 1615 | }, 1616 | "type": "library", 1617 | "extra": { 1618 | "branch-alias": { 1619 | "dev-master": "1.3.x-dev" 1620 | } 1621 | }, 1622 | "autoload": { 1623 | "classmap": [ 1624 | "src/" 1625 | ] 1626 | }, 1627 | "notification-url": "https://packagist.org/downloads/", 1628 | "license": [ 1629 | "BSD-3-Clause" 1630 | ], 1631 | "authors": [ 1632 | { 1633 | "name": "Sebastian Bergmann", 1634 | "email": "sebastian@phpunit.de" 1635 | } 1636 | ], 1637 | "description": "Provides functionality to handle HHVM/PHP environments", 1638 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1639 | "keywords": [ 1640 | "Xdebug", 1641 | "environment", 1642 | "hhvm" 1643 | ], 1644 | "time": "2015-12-02 08:37:27" 1645 | }, 1646 | { 1647 | "name": "sebastian/exporter", 1648 | "version": "1.2.1", 1649 | "source": { 1650 | "type": "git", 1651 | "url": "https://github.com/sebastianbergmann/exporter.git", 1652 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e" 1653 | }, 1654 | "dist": { 1655 | "type": "zip", 1656 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", 1657 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e", 1658 | "shasum": "" 1659 | }, 1660 | "require": { 1661 | "php": ">=5.3.3", 1662 | "sebastian/recursion-context": "~1.0" 1663 | }, 1664 | "require-dev": { 1665 | "phpunit/phpunit": "~4.4" 1666 | }, 1667 | "type": "library", 1668 | "extra": { 1669 | "branch-alias": { 1670 | "dev-master": "1.2.x-dev" 1671 | } 1672 | }, 1673 | "autoload": { 1674 | "classmap": [ 1675 | "src/" 1676 | ] 1677 | }, 1678 | "notification-url": "https://packagist.org/downloads/", 1679 | "license": [ 1680 | "BSD-3-Clause" 1681 | ], 1682 | "authors": [ 1683 | { 1684 | "name": "Jeff Welch", 1685 | "email": "whatthejeff@gmail.com" 1686 | }, 1687 | { 1688 | "name": "Volker Dusch", 1689 | "email": "github@wallbash.com" 1690 | }, 1691 | { 1692 | "name": "Bernhard Schussek", 1693 | "email": "bschussek@2bepublished.at" 1694 | }, 1695 | { 1696 | "name": "Sebastian Bergmann", 1697 | "email": "sebastian@phpunit.de" 1698 | }, 1699 | { 1700 | "name": "Adam Harvey", 1701 | "email": "aharvey@php.net" 1702 | } 1703 | ], 1704 | "description": "Provides the functionality to export PHP variables for visualization", 1705 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1706 | "keywords": [ 1707 | "export", 1708 | "exporter" 1709 | ], 1710 | "time": "2015-06-21 07:55:53" 1711 | }, 1712 | { 1713 | "name": "sebastian/global-state", 1714 | "version": "1.1.1", 1715 | "source": { 1716 | "type": "git", 1717 | "url": "https://github.com/sebastianbergmann/global-state.git", 1718 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1719 | }, 1720 | "dist": { 1721 | "type": "zip", 1722 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1723 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1724 | "shasum": "" 1725 | }, 1726 | "require": { 1727 | "php": ">=5.3.3" 1728 | }, 1729 | "require-dev": { 1730 | "phpunit/phpunit": "~4.2" 1731 | }, 1732 | "suggest": { 1733 | "ext-uopz": "*" 1734 | }, 1735 | "type": "library", 1736 | "extra": { 1737 | "branch-alias": { 1738 | "dev-master": "1.0-dev" 1739 | } 1740 | }, 1741 | "autoload": { 1742 | "classmap": [ 1743 | "src/" 1744 | ] 1745 | }, 1746 | "notification-url": "https://packagist.org/downloads/", 1747 | "license": [ 1748 | "BSD-3-Clause" 1749 | ], 1750 | "authors": [ 1751 | { 1752 | "name": "Sebastian Bergmann", 1753 | "email": "sebastian@phpunit.de" 1754 | } 1755 | ], 1756 | "description": "Snapshotting of global state", 1757 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1758 | "keywords": [ 1759 | "global state" 1760 | ], 1761 | "time": "2015-10-12 03:26:01" 1762 | }, 1763 | { 1764 | "name": "sebastian/recursion-context", 1765 | "version": "1.0.2", 1766 | "source": { 1767 | "type": "git", 1768 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1769 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791" 1770 | }, 1771 | "dist": { 1772 | "type": "zip", 1773 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", 1774 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791", 1775 | "shasum": "" 1776 | }, 1777 | "require": { 1778 | "php": ">=5.3.3" 1779 | }, 1780 | "require-dev": { 1781 | "phpunit/phpunit": "~4.4" 1782 | }, 1783 | "type": "library", 1784 | "extra": { 1785 | "branch-alias": { 1786 | "dev-master": "1.0.x-dev" 1787 | } 1788 | }, 1789 | "autoload": { 1790 | "classmap": [ 1791 | "src/" 1792 | ] 1793 | }, 1794 | "notification-url": "https://packagist.org/downloads/", 1795 | "license": [ 1796 | "BSD-3-Clause" 1797 | ], 1798 | "authors": [ 1799 | { 1800 | "name": "Jeff Welch", 1801 | "email": "whatthejeff@gmail.com" 1802 | }, 1803 | { 1804 | "name": "Sebastian Bergmann", 1805 | "email": "sebastian@phpunit.de" 1806 | }, 1807 | { 1808 | "name": "Adam Harvey", 1809 | "email": "aharvey@php.net" 1810 | } 1811 | ], 1812 | "description": "Provides functionality to recursively process PHP variables", 1813 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1814 | "time": "2015-11-11 19:50:13" 1815 | }, 1816 | { 1817 | "name": "sebastian/resource-operations", 1818 | "version": "1.0.0", 1819 | "source": { 1820 | "type": "git", 1821 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1822 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 1823 | }, 1824 | "dist": { 1825 | "type": "zip", 1826 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1827 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1828 | "shasum": "" 1829 | }, 1830 | "require": { 1831 | "php": ">=5.6.0" 1832 | }, 1833 | "type": "library", 1834 | "extra": { 1835 | "branch-alias": { 1836 | "dev-master": "1.0.x-dev" 1837 | } 1838 | }, 1839 | "autoload": { 1840 | "classmap": [ 1841 | "src/" 1842 | ] 1843 | }, 1844 | "notification-url": "https://packagist.org/downloads/", 1845 | "license": [ 1846 | "BSD-3-Clause" 1847 | ], 1848 | "authors": [ 1849 | { 1850 | "name": "Sebastian Bergmann", 1851 | "email": "sebastian@phpunit.de" 1852 | } 1853 | ], 1854 | "description": "Provides a list of PHP built-in functions that operate on resources", 1855 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1856 | "time": "2015-07-28 20:34:47" 1857 | }, 1858 | { 1859 | "name": "sebastian/version", 1860 | "version": "1.0.6", 1861 | "source": { 1862 | "type": "git", 1863 | "url": "https://github.com/sebastianbergmann/version.git", 1864 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 1865 | }, 1866 | "dist": { 1867 | "type": "zip", 1868 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1869 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1870 | "shasum": "" 1871 | }, 1872 | "type": "library", 1873 | "autoload": { 1874 | "classmap": [ 1875 | "src/" 1876 | ] 1877 | }, 1878 | "notification-url": "https://packagist.org/downloads/", 1879 | "license": [ 1880 | "BSD-3-Clause" 1881 | ], 1882 | "authors": [ 1883 | { 1884 | "name": "Sebastian Bergmann", 1885 | "email": "sebastian@phpunit.de", 1886 | "role": "lead" 1887 | } 1888 | ], 1889 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1890 | "homepage": "https://github.com/sebastianbergmann/version", 1891 | "time": "2015-06-21 13:59:46" 1892 | }, 1893 | { 1894 | "name": "symfony/event-dispatcher", 1895 | "version": "v2.8.1", 1896 | "source": { 1897 | "type": "git", 1898 | "url": "https://github.com/symfony/event-dispatcher.git", 1899 | "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc" 1900 | }, 1901 | "dist": { 1902 | "type": "zip", 1903 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc", 1904 | "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc", 1905 | "shasum": "" 1906 | }, 1907 | "require": { 1908 | "php": ">=5.3.9" 1909 | }, 1910 | "require-dev": { 1911 | "psr/log": "~1.0", 1912 | "symfony/config": "~2.0,>=2.0.5|~3.0.0", 1913 | "symfony/dependency-injection": "~2.6|~3.0.0", 1914 | "symfony/expression-language": "~2.6|~3.0.0", 1915 | "symfony/stopwatch": "~2.3|~3.0.0" 1916 | }, 1917 | "suggest": { 1918 | "symfony/dependency-injection": "", 1919 | "symfony/http-kernel": "" 1920 | }, 1921 | "type": "library", 1922 | "extra": { 1923 | "branch-alias": { 1924 | "dev-master": "2.8-dev" 1925 | } 1926 | }, 1927 | "autoload": { 1928 | "psr-4": { 1929 | "Symfony\\Component\\EventDispatcher\\": "" 1930 | }, 1931 | "exclude-from-classmap": [ 1932 | "/Tests/" 1933 | ] 1934 | }, 1935 | "notification-url": "https://packagist.org/downloads/", 1936 | "license": [ 1937 | "MIT" 1938 | ], 1939 | "authors": [ 1940 | { 1941 | "name": "Fabien Potencier", 1942 | "email": "fabien@symfony.com" 1943 | }, 1944 | { 1945 | "name": "Symfony Community", 1946 | "homepage": "https://symfony.com/contributors" 1947 | } 1948 | ], 1949 | "description": "Symfony EventDispatcher Component", 1950 | "homepage": "https://symfony.com", 1951 | "time": "2015-10-30 20:15:42" 1952 | }, 1953 | { 1954 | "name": "symfony/stopwatch", 1955 | "version": "v3.0.1", 1956 | "source": { 1957 | "type": "git", 1958 | "url": "https://github.com/symfony/stopwatch.git", 1959 | "reference": "6aeac8907e3e1340a0033b0a9ec075f8e6524800" 1960 | }, 1961 | "dist": { 1962 | "type": "zip", 1963 | "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6aeac8907e3e1340a0033b0a9ec075f8e6524800", 1964 | "reference": "6aeac8907e3e1340a0033b0a9ec075f8e6524800", 1965 | "shasum": "" 1966 | }, 1967 | "require": { 1968 | "php": ">=5.5.9" 1969 | }, 1970 | "type": "library", 1971 | "extra": { 1972 | "branch-alias": { 1973 | "dev-master": "3.0-dev" 1974 | } 1975 | }, 1976 | "autoload": { 1977 | "psr-4": { 1978 | "Symfony\\Component\\Stopwatch\\": "" 1979 | }, 1980 | "exclude-from-classmap": [ 1981 | "/Tests/" 1982 | ] 1983 | }, 1984 | "notification-url": "https://packagist.org/downloads/", 1985 | "license": [ 1986 | "MIT" 1987 | ], 1988 | "authors": [ 1989 | { 1990 | "name": "Fabien Potencier", 1991 | "email": "fabien@symfony.com" 1992 | }, 1993 | { 1994 | "name": "Symfony Community", 1995 | "homepage": "https://symfony.com/contributors" 1996 | } 1997 | ], 1998 | "description": "Symfony Stopwatch Component", 1999 | "homepage": "https://symfony.com", 2000 | "time": "2015-10-30 23:35:59" 2001 | } 2002 | ], 2003 | "aliases": [], 2004 | "minimum-stability": "stable", 2005 | "stability-flags": { 2006 | "satooshi/php-coveralls": 20 2007 | }, 2008 | "prefer-stable": false, 2009 | "prefer-lowest": false, 2010 | "platform": { 2011 | "php": ">5.6" 2012 | }, 2013 | "platform-dev": [] 2014 | } 2015 | -------------------------------------------------------------------------------- /config/commands.config.php: -------------------------------------------------------------------------------- 1 | get('SlimApi\Skeleton\SkeletonInterface'), $container->get('SlimApi\Migration\MigrationInterface')); 6 | }; 7 | 8 | $config['SlimApi\Command\InitDbCommand'] = function($container) { 9 | return new SlimApi\Command\InitDbCommand($container->get('SlimApi\Migration\MigrationInterface')); 10 | }; 11 | 12 | $config['SlimApi\Command\GenerateCommand'] = function($container) { 13 | return new SlimApi\Command\GenerateCommand($container->get('SlimApi\Factory\GeneratorFactory')); 14 | }; 15 | 16 | $config['SlimApi\Command\RoutesCommand'] = function($container) { 17 | return new SlimApi\Command\RoutesCommand; 18 | }; 19 | 20 | $config['commands'] = function ($container) { 21 | $commands = []; 22 | try { 23 | $commands['init:db'] = $container->get('SlimApi\Command\InitDbCommand'); 24 | $commands['generate'] = $container->get('SlimApi\Command\GenerateCommand'); 25 | $commands['routes'] = $container->get('SlimApi\Command\RoutesCommand'); 26 | } catch (Slim\Exception\NotFoundException $e) { 27 | // ignore 28 | $commands = []; 29 | } 30 | $commands['init'] = $container->get('SlimApi\Command\InitCommand'); 31 | return $commands; 32 | }; 33 | 34 | return $config; 35 | -------------------------------------------------------------------------------- /config/services.config.php: -------------------------------------------------------------------------------- 1 | get('templateDir').'/route.txt'), $container->get('namespace')); 6 | }; 7 | 8 | $config['SlimApi\Factory\GeneratorFactory'] = function($container) { 9 | return new SlimApi\Factory\GeneratorFactory(); 10 | }; 11 | 12 | $config['SlimApi\Skeleton\SkeletonInterface'] = function($container) { 13 | return new SlimApi\Skeleton\SkeletonService($container->get('services.skeleton.structure')); 14 | }; 15 | 16 | return $config; 17 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | ./tests/phpunit/ 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ./src/ 28 | 29 | ./src/application.php 30 | ./src/bootstrap.php 31 | ./src/dependencies.php 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/Command/GenerateCommand.php: -------------------------------------------------------------------------------- 1 | generatorFactory = $generatorFactory; 22 | } 23 | 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | protected function configure() 28 | { 29 | $this 30 | ->setName('generate') 31 | ->setAliases(['g']) 32 | ->setDescription('Creates a default slim-api application.') 33 | ->addArgument( 34 | 'type', 35 | InputArgument::REQUIRED, 36 | 'What type of generator? [scaffold, controller, model].' 37 | ) 38 | ->addArgument( 39 | 'name', 40 | InputArgument::REQUIRED, 41 | 'Resultant resource name.' 42 | ) 43 | ->addArgument( 44 | 'fields', 45 | InputArgument::IS_ARRAY, 46 | 'What fields (if appropriate).' 47 | ) 48 | ->addOption( 49 | 'api-version', 50 | null, 51 | InputOption::VALUE_OPTIONAL, 52 | "When creating scaffold/controller/route this surrounds the route in a version" 53 | ) 54 | ->setHelp(<<generate command help to generate controllers/models/routes or all together as scaffold. 56 | Model/scaffold generators take the db definition as extra arguments, in the form name:type:length:nullable:unique in most cases. 57 | slimapi generate scaffold user oauthToken:text::false:true token:string:128:false:true role:string:128:false 58 | In the case of the type being reference the name should be the reference, and it also takes extra arguments for action when foreign key deleted and updated. 59 | slimapi generate scaffold scaffold foo field1:integer field2:string user:reference 60 | slimapi generate scaffold scaffold bar field1:integer field2:string user:reference:::NO_ACTION:CASCADE 61 | EOT 62 | ) 63 | ; 64 | } 65 | 66 | /** 67 | * {@inheritdoc} 68 | */ 69 | protected function execute(InputInterface $input, OutputInterface $output) 70 | { 71 | $type = $input->getArgument('type'); 72 | if (!in_array($type, ['scaffold', 'controller', 'model', 'migration'])) { 73 | throw new Exception('Invalid type.'); 74 | } 75 | 76 | $name = ucfirst($input->getArgument('name')); 77 | $pattern = '/^[A-Z][a-zA-Z0-9]*$/'; 78 | if (1 !== preg_match($pattern, $name)) { 79 | throw new Exception('Invalid name.'); 80 | } 81 | 82 | $fields = $input->getArgument('fields'); 83 | if (!is_array($fields)) { 84 | throw new Exception('Invalid fields.'); 85 | } 86 | 87 | if (false === is_file('composer.json')) { 88 | throw new Exception('Commands must be run from root of project.'); 89 | } 90 | 91 | $version = $input->getOption('api-version'); 92 | 93 | $generator = $this->generatorFactory->fetch($type); 94 | if (!$generator->validate($name, $fields)) { 95 | throw new Exception('Fields not valid.'); 96 | } 97 | 98 | try { 99 | $generator->process($name, $fields, ['version' => $version]); 100 | $output->writeln('Generation completed.'); 101 | } catch (Exception $e) { 102 | echo $e->getMessage(); 103 | } 104 | 105 | return true; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/Command/InitCommand.php: -------------------------------------------------------------------------------- 1 | skeletonService = $skeletonService; 25 | $this->migrationService = $migrationService; 26 | } 27 | 28 | /** 29 | * {@inheritdoc} 30 | */ 31 | protected function configure() 32 | { 33 | $this 34 | ->setName('init') 35 | ->setDescription('Creates a default slim-api application.') 36 | ->addArgument( 37 | 'name', 38 | InputArgument::REQUIRED, 39 | 'Application name (becomes namespace).' 40 | ) 41 | ->addArgument( 42 | 'location', 43 | InputArgument::OPTIONAL, 44 | 'Where do you want to create the application?', 45 | getcwd() 46 | ) 47 | ; 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | protected function execute(InputInterface $input, OutputInterface $output) 54 | { 55 | $name = ucfirst($input->getArgument('name')); 56 | $pattern = '/^[A-Z][a-zA-Z0-9]*$/'; 57 | if (1 !== preg_match($pattern, $name)) { 58 | throw new Exception('Invalid name.'); 59 | } 60 | 61 | $path = $input->getArgument('location'); 62 | $path = ('/' === $path[0]) ? $path : getcwd().'/'.$path; 63 | $pathExists = is_dir($path); 64 | $pathInfo = pathinfo($path); 65 | if ( 66 | ($pathExists && !is_writable($path)) || 67 | (!$pathExists && !is_writable($pathInfo['dirname'])) 68 | ) { 69 | throw new Exception('Cannot write to path.'); 70 | } 71 | 72 | if ($pathExists && 2 !== count(scandir($path))) { 73 | throw new Exception('Path not empty.'); 74 | } 75 | 76 | try { 77 | $this->skeletonService->create($path, $name); 78 | $this->migrationService->init($path); 79 | $output->writeln(''.static::$successMessage.''); 80 | } catch (Exception $e) { 81 | $output->writeln($e->getMessage()); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Command/InitDbCommand.php: -------------------------------------------------------------------------------- 1 | databaseService = $databaseService; 24 | } 25 | 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | protected function configure() 30 | { 31 | $this 32 | ->setName('init:db') 33 | ->setDescription('Initiates the db setup.') 34 | ; 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | protected function execute(InputInterface $input, OutputInterface $output) 41 | { 42 | if (false === is_file('composer.json')) { 43 | throw new Exception('Commands must be run from root of project.'); 44 | } 45 | 46 | try { 47 | $this->databaseService->init(getcwd()); 48 | $output->writeln(''.static::$successMessage.''); 49 | } catch (Exception $e) { 50 | $output->writeln($e->getMessage()); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Command/RoutesCommand.php: -------------------------------------------------------------------------------- 1 | setName('routes') 21 | ->setDescription('Retrieves routes for app.') 22 | ; 23 | } 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | protected function execute(InputInterface $input, OutputInterface $output) 29 | { 30 | if (false === is_file('composer.json')) { 31 | throw new Exception('Commands must be run from root of project.'); 32 | } 33 | 34 | try { 35 | $app = new App(); 36 | require 'src/routes.php'; 37 | $routes = $app->getContainer()->get('router')->getRoutes(); 38 | foreach ($routes as $route) { 39 | foreach ($route->getMethods() as $method) { 40 | $name = str_pad($route->getName(), 10, ' ', STR_PAD_LEFT); 41 | $method = str_pad($method, 8, ' ', STR_PAD_RIGHT); 42 | $routeStr = str_pad($route->getPattern(), 15, ' ', STR_PAD_RIGHT); 43 | $resolvesTo = (is_string($route->getCallable()) ? $route->getCallable() : ''); 44 | $output->writeln(''.$name.$method.$routeStr.$resolvesTo.''); 45 | } 46 | } 47 | } catch (Exception $e) { 48 | $output->writeln($e->getMessage()); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Factory/GeneratorFactory.php: -------------------------------------------------------------------------------- 1 | generators)) { 21 | $generator = $this->generators[$name]; 22 | } 23 | return $generator; 24 | } 25 | 26 | /** 27 | * Add a generator to the factory 28 | * 29 | * @param string $name the name of the Generator 30 | * @param GeneratorInterface $class the generator object to return for the specified name 31 | */ 32 | public function add($name, GeneratorInterface $class) 33 | { 34 | if (array_key_exists($name, $this->generators)) { 35 | throw new \InvalidArgumentException('Generator already exists.'); 36 | } 37 | 38 | $this->generators[$name] = $class; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Generator/GeneratorInterface.php: -------------------------------------------------------------------------------- 1 | [ 23 | 'SlimApi\Phinx', //provides migrations 24 | 'SlimApi\Mvc' //provides structure 25 | ] 26 | ]; 27 | } else { 28 | // load the target autoloader 29 | require 'vendor/autoload.php'; 30 | } 31 | 32 | foreach ($config['slim-api']['modules'] as $moduleNamespace) { 33 | $config = array_merge($config, $moduleService->load($moduleNamespace)); 34 | } 35 | 36 | return $config; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Service/ConfigService.php: -------------------------------------------------------------------------------- 1 | dependencyFileLocation = $dependencyFileLocation; 20 | $this->namespaceRoot = $namespaceRoot; 21 | } 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function processCommand($type, ...$arguments) 27 | { 28 | $name = array_shift($arguments); 29 | $template = $this->fetch($type); 30 | if ($template) { 31 | $this->addDependency($name, $template); 32 | } else { 33 | throw new \Exception('Invalid dependency command.'); 34 | } 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | public function create($name, $options = []) 41 | { 42 | $content = PHP_EOL.implode(PHP_EOL.PHP_EOL, $this->commands); 43 | $this->commands = []; 44 | $origContent = file($this->targetLocation($name)); 45 | // insert content just before the return statement 46 | // @todo: something neater? 47 | array_splice($origContent, count($origContent)-2, 0, $content); 48 | return file_put_contents($this->targetLocation($name), $origContent); 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | public function targetLocation($name) 55 | { 56 | return $this->dependencyFileLocation; 57 | } 58 | 59 | /** 60 | * Add the dependency processed template to our command array 61 | * 62 | * @param string $name 63 | * @param string $template 64 | * 65 | * @return void 66 | */ 67 | private function addDependency($name, $template) 68 | { 69 | $this->commands[] = strtr($template, ['$namespace' => $this->namespaceRoot, '$name' => $name]); 70 | } 71 | 72 | /** 73 | * Fetches appropriate template 74 | * 75 | * @param string $name 76 | * 77 | * @return GeneratorInterface|false the required template or false if none. 78 | */ 79 | public function fetch($name) 80 | { 81 | $template = false; 82 | if (array_key_exists($name, $this->templates)) { 83 | $template = $this->templates[$name]; 84 | } 85 | return $template; 86 | } 87 | 88 | /** 89 | * Add a template to the factory 90 | * 91 | * @param string $name the name of the Generator 92 | * @param string $template the template to return for the specified name 93 | */ 94 | public function add($name, $template) 95 | { 96 | if (array_key_exists($name, $this->templates)) { 97 | throw new \InvalidArgumentException('Template already exists.'); 98 | } 99 | 100 | $this->templates[$name] = $template; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/Service/ModuleService.php: -------------------------------------------------------------------------------- 1 | loadDependencies(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Service/RouteService.php: -------------------------------------------------------------------------------- 1 | routerFileLocation = $routerFileLocation; 20 | $this->template = $routeTemplate; 21 | $this->controllerLocation = $namespaceRoot.'\Controller\$nameController'; 22 | } 23 | 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function processCommand($type, ...$arguments) 28 | { 29 | // $arguments is method1, method2 etc 30 | array_shift($arguments); 31 | switch ($type) { 32 | case 'addRoute': 33 | foreach ($arguments as $method) { 34 | $this->addRoute($method); 35 | } 36 | break; 37 | default: 38 | throw new \Exception('Invalid route command.'); 39 | break; 40 | } 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function create($name, $options = []) 47 | { 48 | $version = '/'.(array_key_exists('version', $options) ? $options['version'] : ''); 49 | $content = PHP_EOL.PHP_EOL.implode(PHP_EOL, $this->commands); 50 | $content = strtr($content, ['$route' => '/'.strtolower($name), '$name' => $name, '$version' => $version]); 51 | return file_put_contents($this->targetLocation($name), $content, FILE_APPEND); 52 | } 53 | 54 | /** 55 | * {@inheritdoc} 56 | */ 57 | public function targetLocation($name) 58 | { 59 | return $this->routerFileLocation; 60 | } 61 | 62 | /** 63 | * Process the requrested method into a route template 64 | * 65 | * @param string $method 66 | * 67 | * @return void 68 | */ 69 | private function addRoute($method) 70 | { 71 | switch ($method) { 72 | case 'index': 73 | $methodMap = ['GET']; 74 | $realRoute = '$route'; 75 | $controllerCallable = $this->controllerLocation.':indexAction'; 76 | break; 77 | case 'get': 78 | $methodMap = ['GET']; 79 | $realRoute = '$route/{id}'; 80 | $controllerCallable = $this->controllerLocation.':getAction'; 81 | break; 82 | case 'post': 83 | $methodMap = ['POST']; 84 | $realRoute = '$route'; 85 | $controllerCallable = $this->controllerLocation.':postAction'; 86 | break; 87 | case 'put': 88 | $methodMap = ['POST', 'PUT']; 89 | $realRoute = '$route/{id}'; 90 | $controllerCallable = $this->controllerLocation.':putAction'; 91 | break; 92 | case 'delete': 93 | $methodMap = ['DELETE']; 94 | $realRoute = '$route/{id}'; 95 | $controllerCallable = $this->controllerLocation.':deleteAction'; 96 | break; 97 | default: 98 | throw new \Exception('Invalid method.'.$method); 99 | break; 100 | } 101 | $methodMap = "['".implode("', '", $methodMap)."']"; 102 | $command = strtr($this->template, ['$methodMap' => $methodMap, '$route' => $realRoute, '$controllerCallable' => $controllerCallable]); 103 | // $app->map(['GET'], '/trails', 'EarlyBird\Controllers\TrailsController:index'); 104 | // $app->map(['GET'], '/texts/{stage}', 'EarlyBird\Controllers\TrailsController:get'); 105 | // $app->map(['POST'], '/trails', 'EarlyBird\Controllers\TrailsController:post'); 106 | // $app->map(['POST', 'PUT'], '/trails/{id}', 'EarlyBird\Controllers\TrailsController:put'); 107 | $this->commands[] = $command; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/Skeleton/SkeletonInterface.php: -------------------------------------------------------------------------------- 1 | structure = $structure; 12 | } 13 | 14 | /** 15 | * {@inheritdoc} 16 | */ 17 | public function create($path, $name, $structure = false) 18 | { 19 | if (false === $structure) { 20 | $structure = $this->structure; 21 | } 22 | 23 | // should only happen the first time 24 | if ( ! is_dir($path)) { 25 | mkdir($path, 0777, true); 26 | } 27 | 28 | foreach ($structure as $folder => $subFolder) { 29 | // Folder with subfolders 30 | if (is_array($subFolder)) { 31 | $newPath = "{$path}/{$folder}"; 32 | if ( ! is_dir($newPath)) { 33 | mkdir($newPath); 34 | } 35 | $this->create($newPath, $name, $subFolder); 36 | } else { 37 | // filename with content 38 | $content = strtr($subFolder, ['$name' => $name]); 39 | $filePath = "{$path}/{$folder}"; 40 | if ( ! is_file($filePath)) { 41 | file_put_contents($filePath, $content); 42 | } 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/application.php: -------------------------------------------------------------------------------- 1 | addCommands($container->get('commands')); 4 | $application->run(); 5 | -------------------------------------------------------------------------------- /src/bootstrap.php: -------------------------------------------------------------------------------- 1 | loadDependencies()); 3 | 4 | foreach ($container->get('slim-api')['modules'] as $moduleNamespace) { 5 | $container->get($moduleNamespace.'\Init'); 6 | } 7 | 8 | require 'application.php'; 9 | -------------------------------------------------------------------------------- /tests/phpunit/Command/GenerateCommandTest.php: -------------------------------------------------------------------------------- 1 | getMockBuilder('SlimApi\Factory\GeneratorFactory') 22 | ->disableOriginalConstructor() 23 | ->getMock(); 24 | $generatorFactory->method('fetch') 25 | ->willReturn(new MockModelGeneratorMock); 26 | 27 | $application = new Application('SlimApi', '@package_version@'); 28 | $application->add(new GenerateCommand($generatorFactory)); 29 | $this->command = $application->find('generate'); 30 | $this->tester = new CommandTester($this->command); 31 | } 32 | 33 | public function testNotEnoughArgs1() 34 | { 35 | $this->setExpectedException('Exception', 'Not enough arguments (missing: "name").'); 36 | $this->tester->execute([ 37 | 'command' => $this->command->getName(), 38 | 'type' => '5foo' 39 | ]); 40 | } 41 | 42 | public function testNotEnoughArgs2() 43 | { 44 | $this->setExpectedException('Exception', 'Not enough arguments (missing: "type").'); 45 | $this->tester->execute([ 46 | 'command' => $this->command->getName(), 47 | 'name' => 'bar' 48 | ]); 49 | } 50 | 51 | public function testInvalidType() 52 | { 53 | $this->setExpectedException('Exception', 'Invalid type.'); 54 | $this->tester->execute([ 55 | 'command' => $this->command->getName(), 56 | 'type' => '5foo', 57 | 'name' => 'bar' 58 | ]); 59 | } 60 | 61 | public function testInvalidName() 62 | { 63 | $this->setExpectedException('Exception', 'Invalid name.'); 64 | $this->tester->execute([ 65 | 'command' => $this->command->getName(), 66 | 'type' => 'scaffold', 67 | 'name' => '5bar' 68 | ]); 69 | } 70 | 71 | public function testInvalidFields() 72 | { 73 | $this->setExpectedException('Exception', 'Invalid fields.'); 74 | $this->tester->execute([ 75 | 'command' => $this->command->getName(), 76 | 'type' => 'scaffold', 77 | 'name' => 'bar', 78 | 'fields' => 'some' 79 | ]); 80 | } 81 | 82 | public function testRunFromInvalidPath() 83 | { 84 | $this->setupDirectory(); 85 | chdir('src/Model'); 86 | $this->setExpectedException('Exception', 'Commands must be run from root of project.'); 87 | $this->tester->execute([ 88 | 'command' => $this->command->getName(), 89 | 'type' => 'model', 90 | 'name' => 'bar' 91 | ]); 92 | } 93 | 94 | public function testModelExists() 95 | { 96 | $this->setupDirectory(); 97 | $modelContent = 'setExpectedException('Exception', 'Fields not valid.'); 101 | $this->tester->execute([ 102 | 'command' => $this->command->getName(), 103 | 'type' => 'model', 104 | 'name' => 'bar' 105 | ]); 106 | } 107 | 108 | public function testProcessException() 109 | { 110 | $generatorFactory = $this->getMockBuilder('SlimApi\Factory\GeneratorFactory') 111 | ->disableOriginalConstructor() 112 | ->getMock(); 113 | $generatorFactory->method('fetch') 114 | ->willReturn(new MockModelGeneratorMock2); 115 | 116 | $application = new Application('SlimApi', '@package_version@'); 117 | $application->add(new GenerateCommand($generatorFactory)); 118 | $tester = new CommandTester($application->find('generate')); 119 | 120 | $result = $tester->execute([ 121 | 'command' => $this->command->getName(), 122 | 'type' => 'model', 123 | 'name' => 'baz' 124 | ]); 125 | $this->assertEquals(0, $result); 126 | } 127 | 128 | public function testSuccess() 129 | { 130 | $generatorFactory = $this->getMockBuilder('SlimApi\Factory\GeneratorFactory') 131 | ->disableOriginalConstructor() 132 | ->getMock(); 133 | $generatorFactory->method('fetch') 134 | ->willReturn(new MockModelGeneratorMock2); 135 | 136 | $application = new Application('SlimApi', '@package_version@'); 137 | $application->add(new GenerateCommand($generatorFactory)); 138 | $this->command = $application->find('generate'); 139 | $this->tester = new CommandTester($this->command); 140 | 141 | $result = $this->tester->execute([ 142 | 'command' => $this->command->getName(), 143 | 'type' => 'model', 144 | 'name' => 'baz' 145 | ]); 146 | $this->assertEquals(0, $result); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /tests/phpunit/Command/InitCommandTest.php: -------------------------------------------------------------------------------- 1 | getMockBuilder('SlimApi\Skeleton\SkeletonService') 16 | ->disableOriginalConstructor() 17 | ->getMock(); 18 | $composerServiceMock->method('create'); 19 | 20 | $phinxServiceMock = $this->getMockBuilder('SlimApi\Migration\MigrationInterface') 21 | ->disableOriginalConstructor() 22 | ->getMock(); 23 | $phinxServiceMock->method('init'); 24 | 25 | $application = new Application('SlimApi', '@package_version@'); 26 | $application->add(new InitCommand($composerServiceMock, $phinxServiceMock)); 27 | $this->command = $application->find('init'); 28 | $this->tester = new CommandTester($this->command); 29 | } 30 | 31 | public function testNameMissing() 32 | { 33 | $this->setExpectedException('Exception', 'Not enough arguments (missing: "name").'); 34 | $this->tester->execute([ 35 | 'command' => $this->command->getName(), 36 | ]); 37 | } 38 | 39 | public function testInvalidName1() 40 | { 41 | $this->setExpectedException('Exception', 'Invalid name.'); 42 | $this->tester->execute([ 43 | 'command' => $this->command->getName(), 44 | 'name' => 'Te st', 45 | ]); 46 | } 47 | 48 | public function testInvalidName2() 49 | { 50 | $this->setExpectedException('Exception', 'Invalid name.'); 51 | $this->tester->execute([ 52 | 'command' => $this->command->getName(), 53 | 'name' => 'Te-st', 54 | ]); 55 | } 56 | 57 | public function testValidName1() 58 | { 59 | $this->tester->execute([ 60 | 'command' => $this->command->getName(), 61 | 'name' => 'Test', 62 | 'location' => 'foo', 63 | ]); 64 | } 65 | 66 | public function testValidName2() 67 | { 68 | $this->tester->execute([ 69 | 'command' => $this->command->getName(), 70 | 'name' => 'TeSt', 71 | 'location' => 'foo', 72 | ]); 73 | } 74 | 75 | public function testValidName3() 76 | { 77 | $this->tester->execute([ 78 | 'command' => $this->command->getName(), 79 | 'name' => 'test', 80 | 'location' => 'foo', 81 | ]); 82 | } 83 | 84 | public function testComposerNotExecutable() 85 | { 86 | $this->setExpectedException('Exception'); 87 | $this->tester->execute([ 88 | 'command' => $this->command->getName(), 89 | 'name' => 'butts', 90 | '--composer-location' => '/etc/composer', 91 | ]); 92 | } 93 | 94 | public function testComposerRelativeExecutable() 95 | { 96 | $this->setExpectedException('Exception'); 97 | $this->tester->execute([ 98 | 'command' => $this->command->getName(), 99 | 'name' => 'butts', 100 | '--composer-location' => 'composer', 101 | ]); 102 | } 103 | 104 | public function testNotEmpty() 105 | { 106 | $this->setExpectedException('Exception', 'Path not empty.'); 107 | $this->tester->execute([ 108 | 'command' => $this->command->getName(), 109 | 'name' => 'Butts', 110 | ]); 111 | } 112 | 113 | public function testNotWritable() 114 | { 115 | $this->setExpectedException('Exception', 'Cannot write to path.'); 116 | $this->tester->execute([ 117 | 'command' => $this->command->getName(), 118 | 'name' => 'Butts', 119 | 'location' => '/etc', 120 | ]); 121 | } 122 | 123 | public function testNotWritable2() 124 | { 125 | $this->setExpectedException('Exception', 'Cannot write to path.'); 126 | $this->tester->execute([ 127 | 'command' => $this->command->getName(), 128 | 'name' => 'Butts', 129 | 'location' => '/etc/butts', 130 | ]); 131 | } 132 | 133 | public function testRelative() 134 | { 135 | $this->tester->execute([ 136 | 'command' => $this->command->getName(), 137 | 'name' => 'Butts', 138 | 'location' => 'butts', 139 | ]); 140 | $this->assertEquals(InitCommand::$successMessage, trim($this->tester->getDisplay())); 141 | } 142 | 143 | public function testExecuteException() 144 | { 145 | $this->command->migrationService->method('init')->will($this->throwException(new \Exception('Foo exception'))); 146 | 147 | $this->tester->execute([ 148 | 'command' => $this->command->getName(), 149 | 'name' => 'Butts', 150 | 'location' => 'butts', 151 | ]); 152 | $this->assertEquals('Foo exception'.PHP_EOL, $this->tester->getDisplay()); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /tests/phpunit/Command/InitDbCommandTest.php: -------------------------------------------------------------------------------- 1 | getMockBuilder('SlimApi\Migration\MigrationInterface') 18 | ->disableOriginalConstructor() 19 | ->getMock(); 20 | $phinxServiceMock->method('init'); 21 | 22 | $application = new Application('SlimApi', '@package_version@'); 23 | $application->add(new InitDbCommand($phinxServiceMock)); 24 | $this->command = $application->find('init:db'); 25 | $this->tester = new CommandTester($this->command); 26 | } 27 | 28 | public function testMustComposer() 29 | { 30 | $this->setupDirectory(); 31 | chdir('src'); 32 | $this->setExpectedException('Exception', 'Commands must be run from root of project.'); 33 | $this->tester->execute(['command' => $this->command->getName()]); 34 | } 35 | 36 | public function testInit() 37 | { 38 | $this->setupDirectory(); 39 | $this->tester->execute(['command' => $this->command->getName()]); 40 | $this->assertEquals(InitDbCommand::$successMessage, trim($this->tester->getDisplay())); 41 | } 42 | 43 | public function testExecuteException() 44 | { 45 | $this->command->databaseService->method('init')->will($this->throwException(new \Exception('Foo exception'))); 46 | 47 | $this->setupDirectory(); 48 | $this->tester->execute(['command' => $this->command->getName()]); 49 | $this->assertEquals('Foo exception'.PHP_EOL, $this->tester->getDisplay()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/phpunit/Command/RoutesCommandTest.php: -------------------------------------------------------------------------------- 1 | add(new RoutesCommand); 22 | $this->command = $application->find('routes'); 23 | $this->tester = new CommandTester($this->command); 24 | $this->setupDirectory(); 25 | } 26 | 27 | public function testMustComposer() 28 | { 29 | chdir('src'); 30 | $this->setExpectedException('Exception', 'Commands must be run from root of project.'); 31 | $this->tester->execute(['command' => $this->command->getName()]); 32 | } 33 | 34 | public function testNoRoutes() 35 | { 36 | $this->tester->execute(['command' => $this->command->getName()]); 37 | $this->assertEmpty($this->tester->getDisplay()); 38 | } 39 | 40 | public function testMultipleRoutes() 41 | { 42 | $routesFileStr = <<<'EOT' 43 | map(['GET'], '/bar3', 'Fred\Controller\Bar3Controller:indexAction'); 46 | $app->map(['GET'], '/bar3/{id}', 'Fred\Controller\Bar3Controller:getAction'); 47 | $app->map(['POST'], '/bar3', 'Fred\Controller\Bar3Controller:postAction'); 48 | $app->map(['POST', 'PUT'], '/bar3/{id}', 'Fred\Controller\Bar3Controller:putAction'); 49 | $app->map(['DELETE'], '/bar3/{id}', 'Fred\Controller\Bar3Controller:deleteAction'); 50 | EOT; 51 | 52 | file_put_contents('src/routes.php', $routesFileStr); 53 | 54 | $routesOutputStr = <<<'EOT' 55 | GET /bar3 Fred\Controller\Bar3Controller:indexAction 56 | GET /bar3/{id} Fred\Controller\Bar3Controller:getAction 57 | POST /bar3 Fred\Controller\Bar3Controller:postAction 58 | POST /bar3/{id} Fred\Controller\Bar3Controller:putAction 59 | PUT /bar3/{id} Fred\Controller\Bar3Controller:putAction 60 | DELETE /bar3/{id} Fred\Controller\Bar3Controller:deleteAction 61 | 62 | EOT; 63 | $this->tester->execute(['command' => $this->command->getName()]); 64 | $this->assertEquals($routesOutputStr, $this->tester->getDisplay()); 65 | 66 | } 67 | 68 | public function testExecuteException() 69 | { 70 | $routesFileStr = <<<'EOT' 71 | tester->execute(['command' => $this->command->getName()]); 77 | $this->assertEquals('Foo exception'.PHP_EOL, $this->tester->getDisplay()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /tests/phpunit/DirectoryTrait.php: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /tests/phpunit/Factory/GeneratorFactoryTest.php: -------------------------------------------------------------------------------- 1 | generatorFactory = new GeneratorFactory(); 12 | $this->generatorFactory->add('model', new ModelGeneratorMock); 13 | $this->generatorFactory->add('controller', new ModelGeneratorMock); 14 | $this->generatorFactory->add('scaffold', new ModelGeneratorMock); 15 | } 16 | 17 | public function testReturnsModelGenerator() 18 | { 19 | $generator = $this->generatorFactory->fetch('model'); 20 | $this->assertInstanceOf('SlimApi\Generator\GeneratorInterface', $generator); 21 | } 22 | 23 | public function testReturnsControllerGenerator() 24 | { 25 | $generator = $this->generatorFactory->fetch('controller'); 26 | $this->assertInstanceOf('SlimApi\Generator\GeneratorInterface', $generator); 27 | } 28 | 29 | public function testReturnsScaffoldGenerator() 30 | { 31 | $generator = $this->generatorFactory->fetch('scaffold'); 32 | $this->assertInstanceOf('SlimApi\Generator\GeneratorInterface', $generator); 33 | } 34 | 35 | public function testDuplicateFactory() 36 | { 37 | $this->setExpectedException('Exception', 'Generator already exists.'); 38 | $this->generatorFactory->add('model', new ModelGeneratorMock); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/phpunit/Mock/ModelGeneratorMock.php: -------------------------------------------------------------------------------- 1 | setupDirectory(); 13 | $config = <<<'EOT' 14 | 'Fred', 17 | 'slim-api' => [ 18 | 'modules' => [ 19 | 'SlimPhinx', //provides migrations 20 | 'SlimEloquent' //provides ORM 21 | ] 22 | ] 23 | ]; 24 | EOT; 25 | file_put_contents('config/slim-api.config.php', $config); 26 | 27 | $this->configService = new ConfigService; 28 | } 29 | 30 | public function testConfigFile() 31 | { 32 | $configArray = [ 33 | 'namespace' => 'Fred', 34 | 'slim-api' => [ 35 | 'modules' => [ 36 | 'SlimPhinx', //provides migrations 37 | 'SlimEloquent' //provides ORM 38 | ] 39 | ] 40 | ]; 41 | 42 | $this->assertEquals($configArray, $this->configService->fetch()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/phpunit/Service/DependencyServiceTest.php: -------------------------------------------------------------------------------- 1 | setupDirectory(); 13 | $mvcTemplate = <<<'EOT' 14 | dependencyService = new DependencyService('config/mvc.config.php', 'Foo'); 26 | } 27 | 28 | public function testAdd() 29 | { 30 | $this->dependencyService->add('Bar', 'some template'); 31 | $this->assertEquals($this->dependencyService->fetch('Bar'), 'some template'); 32 | } 33 | 34 | public function testAddDupe() 35 | { 36 | $this->setExpectedException('InvalidArgumentException', 'Template already exists.'); 37 | $this->dependencyService->add('Bar', 'some template'); 38 | $this->dependencyService->add('Bar', 'some other template'); 39 | } 40 | 41 | public function testFetchFalse() 42 | { 43 | $this->assertEquals($this->dependencyService->fetch('Bar'), false); 44 | } 45 | 46 | public function testTargetLocation() 47 | { 48 | $this->assertEquals($this->dependencyService->targetLocation('foo'), 'config/mvc.config.php'); 49 | } 50 | 51 | public function testProcessCommand() 52 | { 53 | $this->dependencyService->add('Bar', 'some template'); 54 | $this->dependencyService->processCommand('Bar', 'foo'); 55 | $this->assertEquals($this->dependencyService->commands, ['some template']); 56 | } 57 | 58 | public function testProcessCommandException() 59 | { 60 | $this->setExpectedException('Exception', 'Invalid dependency command.'); 61 | $this->dependencyService->add('Foo', 'some template'); 62 | $this->dependencyService->processCommand('Bar', 'some template'); 63 | } 64 | 65 | public function testCreate() 66 | { 67 | $this->dependencyService->add('Bar', 'some template'); 68 | $this->dependencyService->processCommand('Bar', 'foo'); 69 | $this->dependencyService->create('buz'); 70 | 71 | $mvcFile = <<<'EOT' 72 | assertEquals(file_get_contents('config/mvc.config.php'), $mvcFile); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /tests/phpunit/Service/RouteServiceTest.php: -------------------------------------------------------------------------------- 1 | setupDirectory(); 14 | $routes = <<<'EOT' 15 | map($methodMap, '$route', '$controllerCallable'); 22 | EOT; 23 | 24 | $this->routeService = new RouteService($routerFileLocation, $routeTemplate, 'Foo'); 25 | } 26 | 27 | public function testIndexAction() 28 | { 29 | $this->routeService->processCommand('addRoute', 'addRoute', 'index'); 30 | $this->assertEquals($this->routeService->commands, ['$app->map([\'GET\'], \'$route\', \'Foo\Controller\$nameController:indexAction\');']); 31 | } 32 | 33 | public function testGetAction() 34 | { 35 | $this->routeService->processCommand('addRoute', 'addRoute', 'get'); 36 | $this->assertEquals($this->routeService->commands, ['$app->map([\'GET\'], \'$route/{id}\', \'Foo\Controller\$nameController:getAction\');']); 37 | } 38 | 39 | public function testPostAction() 40 | { 41 | $this->routeService->processCommand('addRoute', 'addRoute', 'post'); 42 | $this->assertEquals($this->routeService->commands, ['$app->map([\'POST\'], \'$route\', \'Foo\Controller\$nameController:postAction\');']); 43 | } 44 | 45 | public function testPutAction() 46 | { 47 | $this->routeService->processCommand('addRoute', 'addRoute', 'put'); 48 | $this->assertEquals($this->routeService->commands, ['$app->map([\'POST\', \'PUT\'], \'$route/{id}\', \'Foo\Controller\$nameController:putAction\');']); 49 | } 50 | 51 | public function testDeleteAction() 52 | { 53 | $this->routeService->processCommand('addRoute', 'addRoute', 'delete'); 54 | $this->assertEquals($this->routeService->commands, ['$app->map([\'DELETE\'], \'$route/{id}\', \'Foo\Controller\$nameController:deleteAction\');']); 55 | } 56 | 57 | public function testInvalidAction() 58 | { 59 | $this->setExpectedException('Exception', 'Invalid method.foo'); 60 | $this->routeService->processCommand('addRoute', 'addRoute', 'foo'); 61 | } 62 | 63 | public function testTargetLocation() 64 | { 65 | $this->assertEquals($this->routeService->targetLocation('foo'), 'src/routes.php'); 66 | } 67 | 68 | public function testInvalidProcessCommand() 69 | { 70 | $this->setExpectedException('Exception', 'Invalid route command.'); 71 | $this->routeService->processCommand('foo', 'addRoute', 'post'); 72 | } 73 | 74 | public function testCreate() 75 | { 76 | $this->routeService->processCommand('addRoute', 'addRoute', 'delete'); 77 | $this->routeService->create('Foo'); 78 | 79 | $routes = <<<'EOT' 80 | map(['DELETE'], '/foo/{id}', 'Foo\Controller\FooController:deleteAction'); 84 | EOT; 85 | $this->assertEquals(file_get_contents($this->routeService->targetLocation('foo')), $routes); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /tests/phpunit/Skeleton/SkeletonServiceTest.php: -------------------------------------------------------------------------------- 1 | root = vfsStream::setup(); 14 | } 15 | 16 | public function testSimpleDirectoryCreation() 17 | { 18 | // should just create the root dir if it doesn't exist and a single file 19 | $structure = ['foo.txt' => 'bar']; 20 | $skeletonService = new SkeletonService($structure); 21 | $skeletonService->create($this->root->url(), 'Baz'); 22 | $this->assertTrue($this->root->hasChild('foo.txt')); 23 | $this->assertEquals('bar', $this->root->getChild('foo.txt')->getContent()); 24 | } 25 | 26 | public function testNonExistantPathSimpleDirectoryCreation() 27 | { 28 | // should just create the root dir if it doesn't exist and a single file 29 | $structure = ['foo.txt' => 'bar']; 30 | $skeletonService = new SkeletonService($structure); 31 | $skeletonService->create($this->root->url().'/fuz', 'Baz'); 32 | $this->assertTrue($this->root->hasChild('fuz/foo.txt')); 33 | $this->assertEquals('bar', $this->root->getChild('fuz/foo.txt')->getContent()); 34 | } 35 | 36 | public function testComplexDirectoryCreation() 37 | { 38 | // should just create the root dir if it doesn't exist and a single file 39 | $structure = ['one' => ['foo.txt' => 'bar']]; 40 | $skeletonService = new SkeletonService($structure); 41 | $skeletonService->create($this->root->url(), 'Baz'); 42 | $this->assertTrue($this->root->hasChild('one/foo.txt')); 43 | $this->assertTrue(is_dir($this->root->url().'/one')); 44 | $this->assertTrue(is_file($this->root->url().'/one/foo.txt')); 45 | $this->assertEquals('bar', $this->root->getChild('one/foo.txt')->getContent()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/phpunit/bootstrap.php: -------------------------------------------------------------------------------- 1 |