├── .gitattributes ├── .gitignore ├── COPYRIGHT_DISCLAIMER.md ├── README.md ├── composer.json ├── composer.lock ├── phpca-config-all.php ├── phpca-config.php ├── public └── index.php ├── src └── ExampleApp │ ├── Core │ ├── Model │ │ ├── Author.php │ │ ├── GenericExampleAppError.php │ │ ├── Greeting.php │ │ ├── GreetingId.php │ │ └── InvalidDomainObjectError.php │ ├── Port │ │ ├── Input │ │ │ ├── Login │ │ │ │ └── LoginUserInputPort.php │ │ │ ├── SayHello │ │ │ │ └── SayHelloInputPort.php │ │ │ ├── UpdateAuthor │ │ │ │ └── UpdateAuthorInputPort.php │ │ │ └── Welcome │ │ │ │ └── WelcomeInputPort.php │ │ ├── Output │ │ │ ├── Config │ │ │ │ └── ConfigOperationsOutputPort.php │ │ │ ├── Db │ │ │ │ ├── GreetingPersistenceError.php │ │ │ │ └── PersistenceGatewayOperationsOutputPort.php │ │ │ └── Security │ │ │ │ ├── InvalidLoginCredentialsError.php │ │ │ │ ├── SecurityOperationsOutputPort.php │ │ │ │ └── UserNotAuthenticatedError.php │ │ └── Presenter │ │ │ ├── ErrorHandlingPresenterOutputPort.php │ │ │ ├── Login │ │ │ └── LoginPresenterOutputPort.php │ │ │ ├── SayHello │ │ │ └── SayHelloPresenterOutputPort.php │ │ │ ├── UpdateAuthor │ │ │ └── UpdateAuthorPresenterOutputPort.php │ │ │ └── Welcome │ │ │ └── WelcomePresenterOutputPort.php │ └── UseCase │ │ ├── Login │ │ └── LoginUserUseCase.php │ │ ├── SayHello │ │ └── SayHelloUseCase.php │ │ ├── UpdateAuthor │ │ └── UpdateAuthorUseCase.php │ │ └── Welcome │ │ └── WelcomeUseCase.php │ └── Infrastructure │ ├── Adapter │ ├── Config │ │ └── ConfigAdapter.php │ ├── Db │ │ ├── FilePersistenceGateway.php │ │ └── PersistenceMapper.php │ ├── Security │ │ └── SessionBackedSecurityAdapter.php │ └── Web │ │ ├── Controller │ │ ├── Login │ │ │ └── LoginController.php │ │ ├── SayHello │ │ │ └── SayHelloController.php │ │ ├── UpdateAuthor │ │ │ └── UpdateAuthorController.php │ │ └── Welcome │ │ │ └── WelcomeController.php │ │ └── Presenter │ │ ├── AbstractWebPresenter.php │ │ ├── Login │ │ └── LoginPresenter.php │ │ ├── SayHello │ │ └── SayHelloPresenter.php │ │ ├── UpdateAuthor │ │ └── UpdateAuthorPresenter.php │ │ └── Welcome │ │ └── WelcomePresenter.php │ └── Application │ ├── App.php │ ├── ResponseEmitter.php │ ├── SapiResponseEmitter.php │ ├── TemplatesProcessor.php │ └── TwigTemplatesProcessor.php ├── templates ├── edit-author.html ├── error.html ├── hello.html ├── login-success.html ├── login.html ├── update-author-success.html └── welcome.html └── tests └── ExampleApp └── Core ├── Model └── GreetingTest.php └── UserCase └── SayHello └── SayHelloUseCaseTest.php /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | vendor 4 | /db 5 | .phpunit.result.cache 6 | /phpca-reports/ 7 | composer.phar -------------------------------------------------------------------------------- /COPYRIGHT_DISCLAIMER.md: -------------------------------------------------------------------------------- 1 | COPYRIGHT DISCLAIMER 2 | -------------------- 3 | 4 | This application is based on the example [application](https://kevinsmith.io/modern-php-without-a-framework/) by 5 | Kevin Smith. 6 | Here is the related [GitHub repository](https://github.com/kevinsmith/no-framework) containing the original source 7 | code. 8 | Please, consult the copyright and licence notices distributed with the orignal code by Kevin Smith. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gushakov/clean-php/c153fae48c5a725b9ab47383658942c1fd1d658e/README.md -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example/simple", 3 | "description": "description", 4 | "minimum-stability": "stable", 5 | "license": "proprietary", 6 | "authors": [ 7 | { 8 | "name": "gushakov", 9 | "email": "gushakov@yahoo.com" 10 | } 11 | ], 12 | "require": { 13 | "php-di/php-di": "^6.3", 14 | "relay/relay": "^2.1", 15 | "laminas/laminas-diactoros": "^2.9", 16 | "middlewares/fast-route": "^2.0", 17 | "middlewares/request-handler": "^2.0", 18 | "narrowspark/http-emitter": "^2.0", 19 | "twig/twig": "^3.0", 20 | "rakibtg/sleekdb": "^2.12" 21 | }, 22 | "require-dev": { 23 | "phpunit/phpunit": "^9.5", 24 | "mockery/mockery": "^1.5", 25 | "v.chetkov/php-clean-architecture": "^0.1.2" 26 | }, 27 | "autoload": { 28 | "classmap": [ 29 | "src/" 30 | ], 31 | "psr-4": { 32 | "ExampleApp\\": "src/ExampleApp/" 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#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "7baebec0323a9fc13302afe773f6b0d1", 8 | "packages": [ 9 | { 10 | "name": "laminas/laminas-diactoros", 11 | "version": "2.24.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/laminas/laminas-diactoros.git", 15 | "reference": "6028af6c3b5ced4d063a680d2483cce67578b902" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6028af6c3b5ced4d063a680d2483cce67578b902", 20 | "reference": "6028af6c3b5ced4d063a680d2483cce67578b902", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "~8.0.0 || ~8.1.0 || ~8.2.0", 25 | "psr/http-factory": "^1.0", 26 | "psr/http-message": "^1.0" 27 | }, 28 | "conflict": { 29 | "zendframework/zend-diactoros": "*" 30 | }, 31 | "provide": { 32 | "psr/http-factory-implementation": "1.0", 33 | "psr/http-message-implementation": "1.0" 34 | }, 35 | "require-dev": { 36 | "ext-curl": "*", 37 | "ext-dom": "*", 38 | "ext-gd": "*", 39 | "ext-libxml": "*", 40 | "http-interop/http-factory-tests": "^0.9.0", 41 | "laminas/laminas-coding-standard": "^2.4.0", 42 | "php-http/psr7-integration-tests": "^1.2", 43 | "phpunit/phpunit": "^9.5.27", 44 | "psalm/plugin-phpunit": "^0.18.4", 45 | "vimeo/psalm": "^5.4" 46 | }, 47 | "type": "library", 48 | "extra": { 49 | "laminas": { 50 | "config-provider": "Laminas\\Diactoros\\ConfigProvider", 51 | "module": "Laminas\\Diactoros" 52 | } 53 | }, 54 | "autoload": { 55 | "files": [ 56 | "src/functions/create_uploaded_file.php", 57 | "src/functions/marshal_headers_from_sapi.php", 58 | "src/functions/marshal_method_from_sapi.php", 59 | "src/functions/marshal_protocol_version_from_sapi.php", 60 | "src/functions/marshal_uri_from_sapi.php", 61 | "src/functions/normalize_server.php", 62 | "src/functions/normalize_uploaded_files.php", 63 | "src/functions/parse_cookie_header.php", 64 | "src/functions/create_uploaded_file.legacy.php", 65 | "src/functions/marshal_headers_from_sapi.legacy.php", 66 | "src/functions/marshal_method_from_sapi.legacy.php", 67 | "src/functions/marshal_protocol_version_from_sapi.legacy.php", 68 | "src/functions/marshal_uri_from_sapi.legacy.php", 69 | "src/functions/normalize_server.legacy.php", 70 | "src/functions/normalize_uploaded_files.legacy.php", 71 | "src/functions/parse_cookie_header.legacy.php" 72 | ], 73 | "psr-4": { 74 | "Laminas\\Diactoros\\": "src/" 75 | } 76 | }, 77 | "notification-url": "https://packagist.org/downloads/", 78 | "license": [ 79 | "BSD-3-Clause" 80 | ], 81 | "description": "PSR HTTP Message implementations", 82 | "homepage": "https://laminas.dev", 83 | "keywords": [ 84 | "http", 85 | "laminas", 86 | "psr", 87 | "psr-17", 88 | "psr-7" 89 | ], 90 | "support": { 91 | "chat": "https://laminas.dev/chat", 92 | "docs": "https://docs.laminas.dev/laminas-diactoros/", 93 | "forum": "https://discourse.laminas.dev", 94 | "issues": "https://github.com/laminas/laminas-diactoros/issues", 95 | "rss": "https://github.com/laminas/laminas-diactoros/releases.atom", 96 | "source": "https://github.com/laminas/laminas-diactoros" 97 | }, 98 | "funding": [ 99 | { 100 | "url": "https://funding.communitybridge.org/projects/laminas-project", 101 | "type": "community_bridge" 102 | } 103 | ], 104 | "time": "2022-12-20T12:22:40+00:00" 105 | }, 106 | { 107 | "name": "laravel/serializable-closure", 108 | "version": "v1.3.0", 109 | "source": { 110 | "type": "git", 111 | "url": "https://github.com/laravel/serializable-closure.git", 112 | "reference": "f23fe9d4e95255dacee1bf3525e0810d1a1b0f37" 113 | }, 114 | "dist": { 115 | "type": "zip", 116 | "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f23fe9d4e95255dacee1bf3525e0810d1a1b0f37", 117 | "reference": "f23fe9d4e95255dacee1bf3525e0810d1a1b0f37", 118 | "shasum": "" 119 | }, 120 | "require": { 121 | "php": "^7.3|^8.0" 122 | }, 123 | "require-dev": { 124 | "nesbot/carbon": "^2.61", 125 | "pestphp/pest": "^1.21.3", 126 | "phpstan/phpstan": "^1.8.2", 127 | "symfony/var-dumper": "^5.4.11" 128 | }, 129 | "type": "library", 130 | "extra": { 131 | "branch-alias": { 132 | "dev-master": "1.x-dev" 133 | } 134 | }, 135 | "autoload": { 136 | "psr-4": { 137 | "Laravel\\SerializableClosure\\": "src/" 138 | } 139 | }, 140 | "notification-url": "https://packagist.org/downloads/", 141 | "license": [ 142 | "MIT" 143 | ], 144 | "authors": [ 145 | { 146 | "name": "Taylor Otwell", 147 | "email": "taylor@laravel.com" 148 | }, 149 | { 150 | "name": "Nuno Maduro", 151 | "email": "nuno@laravel.com" 152 | } 153 | ], 154 | "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", 155 | "keywords": [ 156 | "closure", 157 | "laravel", 158 | "serializable" 159 | ], 160 | "support": { 161 | "issues": "https://github.com/laravel/serializable-closure/issues", 162 | "source": "https://github.com/laravel/serializable-closure" 163 | }, 164 | "time": "2023-01-30T18:31:20+00:00" 165 | }, 166 | { 167 | "name": "middlewares/fast-route", 168 | "version": "v2.0.1", 169 | "source": { 170 | "type": "git", 171 | "url": "https://github.com/middlewares/fast-route.git", 172 | "reference": "01d992358dc6f3a266576bddd9347a04204e7e37" 173 | }, 174 | "dist": { 175 | "type": "zip", 176 | "url": "https://api.github.com/repos/middlewares/fast-route/zipball/01d992358dc6f3a266576bddd9347a04204e7e37", 177 | "reference": "01d992358dc6f3a266576bddd9347a04204e7e37", 178 | "shasum": "" 179 | }, 180 | "require": { 181 | "middlewares/utils": "^3.0", 182 | "nikic/fast-route": "^1.0", 183 | "php": "^7.2 || ^8.0", 184 | "psr/http-server-middleware": "^1.0" 185 | }, 186 | "require-dev": { 187 | "friendsofphp/php-cs-fixer": "^2.0", 188 | "laminas/laminas-diactoros": "^2.3", 189 | "oscarotero/php-cs-fixer-config": "^1.0", 190 | "phpstan/phpstan": "^0.12", 191 | "phpunit/phpunit": "^8|^9", 192 | "squizlabs/php_codesniffer": "^3.0" 193 | }, 194 | "type": "library", 195 | "autoload": { 196 | "psr-4": { 197 | "Middlewares\\": "src/" 198 | } 199 | }, 200 | "notification-url": "https://packagist.org/downloads/", 201 | "license": [ 202 | "MIT" 203 | ], 204 | "description": "Middleware to use FastRoute", 205 | "homepage": "https://github.com/middlewares/fast-route", 206 | "keywords": [ 207 | "FastRoute", 208 | "fast-route", 209 | "http", 210 | "middleware", 211 | "psr-15", 212 | "psr-7", 213 | "router", 214 | "server" 215 | ], 216 | "support": { 217 | "issues": "https://github.com/middlewares/fast-route/issues", 218 | "source": "https://github.com/middlewares/fast-route/tree/v2.0.1" 219 | }, 220 | "time": "2020-12-02T00:05:59+00:00" 221 | }, 222 | { 223 | "name": "middlewares/request-handler", 224 | "version": "v2.0.2", 225 | "source": { 226 | "type": "git", 227 | "url": "https://github.com/middlewares/request-handler.git", 228 | "reference": "f07840434347520c11959caa54ab3476e16ceee2" 229 | }, 230 | "dist": { 231 | "type": "zip", 232 | "url": "https://api.github.com/repos/middlewares/request-handler/zipball/f07840434347520c11959caa54ab3476e16ceee2", 233 | "reference": "f07840434347520c11959caa54ab3476e16ceee2", 234 | "shasum": "" 235 | }, 236 | "require": { 237 | "middlewares/utils": "^3.0", 238 | "php": "^7.2 || ^8.0", 239 | "psr/container": "^1.0||^2.0", 240 | "psr/http-server-middleware": "^1.0" 241 | }, 242 | "require-dev": { 243 | "friendsofphp/php-cs-fixer": "^2.0", 244 | "laminas/laminas-diactoros": "^2.3", 245 | "oscarotero/php-cs-fixer-config": "^1.0", 246 | "phpstan/phpstan": "^0.12", 247 | "phpunit/phpunit": "^8|^9", 248 | "squizlabs/php_codesniffer": "^3.0" 249 | }, 250 | "type": "library", 251 | "autoload": { 252 | "psr-4": { 253 | "Middlewares\\": "src/" 254 | } 255 | }, 256 | "notification-url": "https://packagist.org/downloads/", 257 | "license": [ 258 | "MIT" 259 | ], 260 | "description": "Middleware to execute request handlers", 261 | "homepage": "https://github.com/middlewares/request-handler", 262 | "keywords": [ 263 | "controller", 264 | "handler", 265 | "http", 266 | "invoke", 267 | "middleware", 268 | "psr-15", 269 | "psr-7", 270 | "request", 271 | "server" 272 | ], 273 | "support": { 274 | "issues": "https://github.com/middlewares/request-handler/issues", 275 | "source": "https://github.com/middlewares/request-handler/tree/v2.0.2" 276 | }, 277 | "time": "2022-05-09T13:49:03+00:00" 278 | }, 279 | { 280 | "name": "middlewares/utils", 281 | "version": "v3.3.0", 282 | "source": { 283 | "type": "git", 284 | "url": "https://github.com/middlewares/utils.git", 285 | "reference": "670b135ce0dbd040eadb025a9388f9bd617cc010" 286 | }, 287 | "dist": { 288 | "type": "zip", 289 | "url": "https://api.github.com/repos/middlewares/utils/zipball/670b135ce0dbd040eadb025a9388f9bd617cc010", 290 | "reference": "670b135ce0dbd040eadb025a9388f9bd617cc010", 291 | "shasum": "" 292 | }, 293 | "require": { 294 | "php": "^7.2 || ^8.0", 295 | "psr/container": "^1.0 || ^2.0", 296 | "psr/http-factory": "^1.0", 297 | "psr/http-message": "^1.0", 298 | "psr/http-server-middleware": "^1.0" 299 | }, 300 | "require-dev": { 301 | "friendsofphp/php-cs-fixer": "^v2.16", 302 | "guzzlehttp/psr7": "^2.0", 303 | "laminas/laminas-diactoros": "^2.4", 304 | "nyholm/psr7": "^1.0", 305 | "oscarotero/php-cs-fixer-config": "^1.0", 306 | "phpstan/phpstan": "^0.12", 307 | "phpunit/phpunit": "^8|^9", 308 | "slim/psr7": "^1.4", 309 | "squizlabs/php_codesniffer": "^3.5", 310 | "sunrise/http-message": "^1.0", 311 | "sunrise/http-server-request": "^1.0", 312 | "sunrise/stream": "^1.0.15", 313 | "sunrise/uri": "^1.0.15" 314 | }, 315 | "type": "library", 316 | "autoload": { 317 | "psr-4": { 318 | "Middlewares\\Utils\\": "src/" 319 | } 320 | }, 321 | "notification-url": "https://packagist.org/downloads/", 322 | "license": [ 323 | "MIT" 324 | ], 325 | "description": "Common utils for PSR-15 middleware packages", 326 | "homepage": "https://github.com/middlewares/utils", 327 | "keywords": [ 328 | "PSR-11", 329 | "http", 330 | "middleware", 331 | "psr-15", 332 | "psr-17", 333 | "psr-7" 334 | ], 335 | "support": { 336 | "issues": "https://github.com/middlewares/utils/issues", 337 | "source": "https://github.com/middlewares/utils/tree/v3.3.0" 338 | }, 339 | "time": "2021-07-04T17:56:23+00:00" 340 | }, 341 | { 342 | "name": "narrowspark/http-emitter", 343 | "version": "v2.0.4", 344 | "source": { 345 | "type": "git", 346 | "url": "https://github.com/narrowspark/http-emitter.git", 347 | "reference": "f59d82980554c8d827dec47eee190ff67995a2f1" 348 | }, 349 | "dist": { 350 | "type": "zip", 351 | "url": "https://api.github.com/repos/narrowspark/http-emitter/zipball/f59d82980554c8d827dec47eee190ff67995a2f1", 352 | "reference": "f59d82980554c8d827dec47eee190ff67995a2f1", 353 | "shasum": "" 354 | }, 355 | "require": { 356 | "php": "^8.0", 357 | "psr/http-message": "^1.0", 358 | "thecodingmachine/safe": "^1.3.3" 359 | }, 360 | "provide": { 361 | "psr/http-message-implementation": "^1.0" 362 | }, 363 | "require-dev": { 364 | "ext-json": "*", 365 | "laminas/laminas-diactoros": "^2.5.0", 366 | "mockery/mockery": "^1.4.2", 367 | "narrowspark/coding-standard": "^5.2.2", 368 | "phpunit/phpunit": "^9.5.2", 369 | "psalm/plugin-mockery": "^0.7.0", 370 | "thecodingmachine/phpstan-safe-rule": "^1.0.1" 371 | }, 372 | "type": "library", 373 | "extra": { 374 | "branch-alias": { 375 | "dev-main": "2.0-dev" 376 | } 377 | }, 378 | "autoload": { 379 | "psr-4": { 380 | "Narrowspark\\HttpEmitter\\": "src/" 381 | }, 382 | "exclude-from-classmap": [ 383 | "tests/" 384 | ] 385 | }, 386 | "notification-url": "https://packagist.org/downloads/", 387 | "license": [ 388 | "MIT" 389 | ], 390 | "authors": [ 391 | { 392 | "name": "Daniel Bannert", 393 | "email": "d.bannert@anolilab.de", 394 | "homepage": "http://www.anolilab.de", 395 | "role": "Developer" 396 | } 397 | ], 398 | "description": "Emitting psr-7 responses.", 399 | "keywords": [ 400 | "emitter", 401 | "http", 402 | "narrowspark", 403 | "psr-7", 404 | "sapi" 405 | ], 406 | "support": { 407 | "issues": "https://github.com/narrowspark/http-emitter/issues", 408 | "source": "https://github.com/narrowspark/http-emitter" 409 | }, 410 | "funding": [ 411 | { 412 | "url": "https://github.com/prisis", 413 | "type": "github" 414 | }, 415 | { 416 | "url": "https://opencollective.com/_prisis_", 417 | "type": "open_collective" 418 | } 419 | ], 420 | "time": "2021-05-17T07:23:36+00:00" 421 | }, 422 | { 423 | "name": "nikic/fast-route", 424 | "version": "v1.3.0", 425 | "source": { 426 | "type": "git", 427 | "url": "https://github.com/nikic/FastRoute.git", 428 | "reference": "181d480e08d9476e61381e04a71b34dc0432e812" 429 | }, 430 | "dist": { 431 | "type": "zip", 432 | "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", 433 | "reference": "181d480e08d9476e61381e04a71b34dc0432e812", 434 | "shasum": "" 435 | }, 436 | "require": { 437 | "php": ">=5.4.0" 438 | }, 439 | "require-dev": { 440 | "phpunit/phpunit": "^4.8.35|~5.7" 441 | }, 442 | "type": "library", 443 | "autoload": { 444 | "files": [ 445 | "src/functions.php" 446 | ], 447 | "psr-4": { 448 | "FastRoute\\": "src/" 449 | } 450 | }, 451 | "notification-url": "https://packagist.org/downloads/", 452 | "license": [ 453 | "BSD-3-Clause" 454 | ], 455 | "authors": [ 456 | { 457 | "name": "Nikita Popov", 458 | "email": "nikic@php.net" 459 | } 460 | ], 461 | "description": "Fast request router for PHP", 462 | "keywords": [ 463 | "router", 464 | "routing" 465 | ], 466 | "support": { 467 | "issues": "https://github.com/nikic/FastRoute/issues", 468 | "source": "https://github.com/nikic/FastRoute/tree/master" 469 | }, 470 | "time": "2018-02-13T20:26:39+00:00" 471 | }, 472 | { 473 | "name": "php-di/invoker", 474 | "version": "2.3.3", 475 | "source": { 476 | "type": "git", 477 | "url": "https://github.com/PHP-DI/Invoker.git", 478 | "reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786" 479 | }, 480 | "dist": { 481 | "type": "zip", 482 | "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/cd6d9f267d1a3474bdddf1be1da079f01b942786", 483 | "reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786", 484 | "shasum": "" 485 | }, 486 | "require": { 487 | "php": ">=7.3", 488 | "psr/container": "^1.0|^2.0" 489 | }, 490 | "require-dev": { 491 | "athletic/athletic": "~0.1.8", 492 | "mnapoli/hard-mode": "~0.3.0", 493 | "phpunit/phpunit": "^9.0" 494 | }, 495 | "type": "library", 496 | "autoload": { 497 | "psr-4": { 498 | "Invoker\\": "src/" 499 | } 500 | }, 501 | "notification-url": "https://packagist.org/downloads/", 502 | "license": [ 503 | "MIT" 504 | ], 505 | "description": "Generic and extensible callable invoker", 506 | "homepage": "https://github.com/PHP-DI/Invoker", 507 | "keywords": [ 508 | "callable", 509 | "dependency", 510 | "dependency-injection", 511 | "injection", 512 | "invoke", 513 | "invoker" 514 | ], 515 | "support": { 516 | "issues": "https://github.com/PHP-DI/Invoker/issues", 517 | "source": "https://github.com/PHP-DI/Invoker/tree/2.3.3" 518 | }, 519 | "funding": [ 520 | { 521 | "url": "https://github.com/mnapoli", 522 | "type": "github" 523 | } 524 | ], 525 | "time": "2021-12-13T09:22:56+00:00" 526 | }, 527 | { 528 | "name": "php-di/php-di", 529 | "version": "6.4.0", 530 | "source": { 531 | "type": "git", 532 | "url": "https://github.com/PHP-DI/PHP-DI.git", 533 | "reference": "ae0f1b3b03d8b29dff81747063cbfd6276246cc4" 534 | }, 535 | "dist": { 536 | "type": "zip", 537 | "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/ae0f1b3b03d8b29dff81747063cbfd6276246cc4", 538 | "reference": "ae0f1b3b03d8b29dff81747063cbfd6276246cc4", 539 | "shasum": "" 540 | }, 541 | "require": { 542 | "laravel/serializable-closure": "^1.0", 543 | "php": ">=7.4.0", 544 | "php-di/invoker": "^2.0", 545 | "php-di/phpdoc-reader": "^2.0.1", 546 | "psr/container": "^1.0" 547 | }, 548 | "provide": { 549 | "psr/container-implementation": "^1.0" 550 | }, 551 | "require-dev": { 552 | "doctrine/annotations": "~1.10", 553 | "friendsofphp/php-cs-fixer": "^2.4", 554 | "mnapoli/phpunit-easymock": "^1.2", 555 | "ocramius/proxy-manager": "^2.11.2", 556 | "phpstan/phpstan": "^0.12", 557 | "phpunit/phpunit": "^9.5" 558 | }, 559 | "suggest": { 560 | "doctrine/annotations": "Install it if you want to use annotations (version ~1.2)", 561 | "ocramius/proxy-manager": "Install it if you want to use lazy injection (version ~2.0)" 562 | }, 563 | "type": "library", 564 | "autoload": { 565 | "files": [ 566 | "src/functions.php" 567 | ], 568 | "psr-4": { 569 | "DI\\": "src/" 570 | } 571 | }, 572 | "notification-url": "https://packagist.org/downloads/", 573 | "license": [ 574 | "MIT" 575 | ], 576 | "description": "The dependency injection container for humans", 577 | "homepage": "https://php-di.org/", 578 | "keywords": [ 579 | "PSR-11", 580 | "container", 581 | "container-interop", 582 | "dependency injection", 583 | "di", 584 | "ioc", 585 | "psr11" 586 | ], 587 | "support": { 588 | "issues": "https://github.com/PHP-DI/PHP-DI/issues", 589 | "source": "https://github.com/PHP-DI/PHP-DI/tree/6.4.0" 590 | }, 591 | "funding": [ 592 | { 593 | "url": "https://github.com/mnapoli", 594 | "type": "github" 595 | }, 596 | { 597 | "url": "https://tidelift.com/funding/github/packagist/php-di/php-di", 598 | "type": "tidelift" 599 | } 600 | ], 601 | "time": "2022-04-09T16:46:38+00:00" 602 | }, 603 | { 604 | "name": "php-di/phpdoc-reader", 605 | "version": "2.2.1", 606 | "source": { 607 | "type": "git", 608 | "url": "https://github.com/PHP-DI/PhpDocReader.git", 609 | "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c" 610 | }, 611 | "dist": { 612 | "type": "zip", 613 | "url": "https://api.github.com/repos/PHP-DI/PhpDocReader/zipball/66daff34cbd2627740ffec9469ffbac9f8c8185c", 614 | "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c", 615 | "shasum": "" 616 | }, 617 | "require": { 618 | "php": ">=7.2.0" 619 | }, 620 | "require-dev": { 621 | "mnapoli/hard-mode": "~0.3.0", 622 | "phpunit/phpunit": "^8.5|^9.0" 623 | }, 624 | "type": "library", 625 | "autoload": { 626 | "psr-4": { 627 | "PhpDocReader\\": "src/PhpDocReader" 628 | } 629 | }, 630 | "notification-url": "https://packagist.org/downloads/", 631 | "license": [ 632 | "MIT" 633 | ], 634 | "description": "PhpDocReader parses @var and @param values in PHP docblocks (supports namespaced class names with the same resolution rules as PHP)", 635 | "keywords": [ 636 | "phpdoc", 637 | "reflection" 638 | ], 639 | "support": { 640 | "issues": "https://github.com/PHP-DI/PhpDocReader/issues", 641 | "source": "https://github.com/PHP-DI/PhpDocReader/tree/2.2.1" 642 | }, 643 | "time": "2020-10-12T12:39:22+00:00" 644 | }, 645 | { 646 | "name": "psr/container", 647 | "version": "1.1.2", 648 | "source": { 649 | "type": "git", 650 | "url": "https://github.com/php-fig/container.git", 651 | "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" 652 | }, 653 | "dist": { 654 | "type": "zip", 655 | "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", 656 | "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", 657 | "shasum": "" 658 | }, 659 | "require": { 660 | "php": ">=7.4.0" 661 | }, 662 | "type": "library", 663 | "autoload": { 664 | "psr-4": { 665 | "Psr\\Container\\": "src/" 666 | } 667 | }, 668 | "notification-url": "https://packagist.org/downloads/", 669 | "license": [ 670 | "MIT" 671 | ], 672 | "authors": [ 673 | { 674 | "name": "PHP-FIG", 675 | "homepage": "https://www.php-fig.org/" 676 | } 677 | ], 678 | "description": "Common Container Interface (PHP FIG PSR-11)", 679 | "homepage": "https://github.com/php-fig/container", 680 | "keywords": [ 681 | "PSR-11", 682 | "container", 683 | "container-interface", 684 | "container-interop", 685 | "psr" 686 | ], 687 | "support": { 688 | "issues": "https://github.com/php-fig/container/issues", 689 | "source": "https://github.com/php-fig/container/tree/1.1.2" 690 | }, 691 | "time": "2021-11-05T16:50:12+00:00" 692 | }, 693 | { 694 | "name": "psr/http-factory", 695 | "version": "1.0.1", 696 | "source": { 697 | "type": "git", 698 | "url": "https://github.com/php-fig/http-factory.git", 699 | "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" 700 | }, 701 | "dist": { 702 | "type": "zip", 703 | "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", 704 | "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", 705 | "shasum": "" 706 | }, 707 | "require": { 708 | "php": ">=7.0.0", 709 | "psr/http-message": "^1.0" 710 | }, 711 | "type": "library", 712 | "extra": { 713 | "branch-alias": { 714 | "dev-master": "1.0.x-dev" 715 | } 716 | }, 717 | "autoload": { 718 | "psr-4": { 719 | "Psr\\Http\\Message\\": "src/" 720 | } 721 | }, 722 | "notification-url": "https://packagist.org/downloads/", 723 | "license": [ 724 | "MIT" 725 | ], 726 | "authors": [ 727 | { 728 | "name": "PHP-FIG", 729 | "homepage": "http://www.php-fig.org/" 730 | } 731 | ], 732 | "description": "Common interfaces for PSR-7 HTTP message factories", 733 | "keywords": [ 734 | "factory", 735 | "http", 736 | "message", 737 | "psr", 738 | "psr-17", 739 | "psr-7", 740 | "request", 741 | "response" 742 | ], 743 | "support": { 744 | "source": "https://github.com/php-fig/http-factory/tree/master" 745 | }, 746 | "time": "2019-04-30T12:38:16+00:00" 747 | }, 748 | { 749 | "name": "psr/http-message", 750 | "version": "1.0.1", 751 | "source": { 752 | "type": "git", 753 | "url": "https://github.com/php-fig/http-message.git", 754 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 755 | }, 756 | "dist": { 757 | "type": "zip", 758 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", 759 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 760 | "shasum": "" 761 | }, 762 | "require": { 763 | "php": ">=5.3.0" 764 | }, 765 | "type": "library", 766 | "extra": { 767 | "branch-alias": { 768 | "dev-master": "1.0.x-dev" 769 | } 770 | }, 771 | "autoload": { 772 | "psr-4": { 773 | "Psr\\Http\\Message\\": "src/" 774 | } 775 | }, 776 | "notification-url": "https://packagist.org/downloads/", 777 | "license": [ 778 | "MIT" 779 | ], 780 | "authors": [ 781 | { 782 | "name": "PHP-FIG", 783 | "homepage": "http://www.php-fig.org/" 784 | } 785 | ], 786 | "description": "Common interface for HTTP messages", 787 | "homepage": "https://github.com/php-fig/http-message", 788 | "keywords": [ 789 | "http", 790 | "http-message", 791 | "psr", 792 | "psr-7", 793 | "request", 794 | "response" 795 | ], 796 | "support": { 797 | "source": "https://github.com/php-fig/http-message/tree/master" 798 | }, 799 | "time": "2016-08-06T14:39:51+00:00" 800 | }, 801 | { 802 | "name": "psr/http-server-handler", 803 | "version": "1.0.1", 804 | "source": { 805 | "type": "git", 806 | "url": "https://github.com/php-fig/http-server-handler.git", 807 | "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7" 808 | }, 809 | "dist": { 810 | "type": "zip", 811 | "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7", 812 | "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7", 813 | "shasum": "" 814 | }, 815 | "require": { 816 | "php": ">=7.0", 817 | "psr/http-message": "^1.0" 818 | }, 819 | "type": "library", 820 | "extra": { 821 | "branch-alias": { 822 | "dev-master": "1.0.x-dev" 823 | } 824 | }, 825 | "autoload": { 826 | "psr-4": { 827 | "Psr\\Http\\Server\\": "src/" 828 | } 829 | }, 830 | "notification-url": "https://packagist.org/downloads/", 831 | "license": [ 832 | "MIT" 833 | ], 834 | "authors": [ 835 | { 836 | "name": "PHP-FIG", 837 | "homepage": "http://www.php-fig.org/" 838 | } 839 | ], 840 | "description": "Common interface for HTTP server-side request handler", 841 | "keywords": [ 842 | "handler", 843 | "http", 844 | "http-interop", 845 | "psr", 846 | "psr-15", 847 | "psr-7", 848 | "request", 849 | "response", 850 | "server" 851 | ], 852 | "support": { 853 | "issues": "https://github.com/php-fig/http-server-handler/issues", 854 | "source": "https://github.com/php-fig/http-server-handler/tree/master" 855 | }, 856 | "time": "2018-10-30T16:46:14+00:00" 857 | }, 858 | { 859 | "name": "psr/http-server-middleware", 860 | "version": "1.0.1", 861 | "source": { 862 | "type": "git", 863 | "url": "https://github.com/php-fig/http-server-middleware.git", 864 | "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5" 865 | }, 866 | "dist": { 867 | "type": "zip", 868 | "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5", 869 | "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5", 870 | "shasum": "" 871 | }, 872 | "require": { 873 | "php": ">=7.0", 874 | "psr/http-message": "^1.0", 875 | "psr/http-server-handler": "^1.0" 876 | }, 877 | "type": "library", 878 | "extra": { 879 | "branch-alias": { 880 | "dev-master": "1.0.x-dev" 881 | } 882 | }, 883 | "autoload": { 884 | "psr-4": { 885 | "Psr\\Http\\Server\\": "src/" 886 | } 887 | }, 888 | "notification-url": "https://packagist.org/downloads/", 889 | "license": [ 890 | "MIT" 891 | ], 892 | "authors": [ 893 | { 894 | "name": "PHP-FIG", 895 | "homepage": "http://www.php-fig.org/" 896 | } 897 | ], 898 | "description": "Common interface for HTTP server-side middleware", 899 | "keywords": [ 900 | "http", 901 | "http-interop", 902 | "middleware", 903 | "psr", 904 | "psr-15", 905 | "psr-7", 906 | "request", 907 | "response" 908 | ], 909 | "support": { 910 | "issues": "https://github.com/php-fig/http-server-middleware/issues", 911 | "source": "https://github.com/php-fig/http-server-middleware/tree/master" 912 | }, 913 | "time": "2018-10-30T17:12:04+00:00" 914 | }, 915 | { 916 | "name": "rakibtg/sleekdb", 917 | "version": "2.15", 918 | "source": { 919 | "type": "git", 920 | "url": "https://github.com/rakibtg/SleekDB.git", 921 | "reference": "957468be56bfc5d23f8f5fa7438e90ede17f9d05" 922 | }, 923 | "dist": { 924 | "type": "zip", 925 | "url": "https://api.github.com/repos/rakibtg/SleekDB/zipball/957468be56bfc5d23f8f5fa7438e90ede17f9d05", 926 | "reference": "957468be56bfc5d23f8f5fa7438e90ede17f9d05", 927 | "shasum": "" 928 | }, 929 | "require": { 930 | "ext-json": "*", 931 | "ext-mbstring": "*", 932 | "php": ">=7.0" 933 | }, 934 | "require-dev": { 935 | "phpunit/phpunit": "^6.5", 936 | "spatie/phpunit-watcher": "^1.8" 937 | }, 938 | "type": "library", 939 | "autoload": { 940 | "psr-4": { 941 | "SleekDB\\": "src/" 942 | } 943 | }, 944 | "notification-url": "https://packagist.org/downloads/", 945 | "license": [ 946 | "MIT" 947 | ], 948 | "authors": [ 949 | { 950 | "name": "rakibtg", 951 | "email": "rakibtg@gmail.com" 952 | } 953 | ], 954 | "description": "SleekDB - A 30Kb NoSQL Database made using PHP", 955 | "keywords": [ 956 | "SleekDB", 957 | "api", 958 | "database", 959 | "flatfile", 960 | "framework", 961 | "micro", 962 | "nosql", 963 | "php", 964 | "rest" 965 | ], 966 | "support": { 967 | "issues": "https://github.com/rakibtg/SleekDB/issues", 968 | "source": "https://github.com/rakibtg/SleekDB/tree/2.15" 969 | }, 970 | "time": "2022-10-16T17:55:55+00:00" 971 | }, 972 | { 973 | "name": "relay/relay", 974 | "version": "2.1.2", 975 | "source": { 976 | "type": "git", 977 | "url": "https://github.com/relayphp/Relay.Relay.git", 978 | "reference": "924fdf9473492d6d221bd7760a8f201f8b35d96c" 979 | }, 980 | "dist": { 981 | "type": "zip", 982 | "url": "https://api.github.com/repos/relayphp/Relay.Relay/zipball/924fdf9473492d6d221bd7760a8f201f8b35d96c", 983 | "reference": "924fdf9473492d6d221bd7760a8f201f8b35d96c", 984 | "shasum": "" 985 | }, 986 | "require": { 987 | "php": ">=7.1", 988 | "psr/http-message": "~1.0", 989 | "psr/http-server-handler": "~1.0", 990 | "psr/http-server-middleware": "^1.0" 991 | }, 992 | "provide": { 993 | "psr/http-server-handler-implementation": "1.0" 994 | }, 995 | "require-dev": { 996 | "doctrine/coding-standard": "^9.0", 997 | "friendsofphp/php-cs-fixer": "^3.0", 998 | "laminas/laminas-diactoros": "~2.2", 999 | "phpstan/phpstan": "^0.12.14", 1000 | "phpunit/phpunit": "~7.0 || ~9.5", 1001 | "roave/security-advisories": "dev-master", 1002 | "vimeo/psalm": "^4.7" 1003 | }, 1004 | "type": "library", 1005 | "autoload": { 1006 | "psr-4": { 1007 | "Relay\\": "src/" 1008 | } 1009 | }, 1010 | "notification-url": "https://packagist.org/downloads/", 1011 | "license": [ 1012 | "MIT" 1013 | ], 1014 | "authors": [ 1015 | { 1016 | "name": "Relay.Relay Contributors", 1017 | "homepage": "https://github.com/relayphp/Relay.Relay/contributors" 1018 | } 1019 | ], 1020 | "description": "A PSR-15 server request handler.", 1021 | "homepage": "https://github.com/relayphp/Relay.Relay", 1022 | "keywords": [ 1023 | "middleware", 1024 | "psr-15", 1025 | "psr-7" 1026 | ], 1027 | "support": { 1028 | "issues": "https://github.com/relayphp/Relay.Relay/issues", 1029 | "source": "https://github.com/relayphp/Relay.Relay/tree/2.1.2" 1030 | }, 1031 | "time": "2021-05-23T05:42:52+00:00" 1032 | }, 1033 | { 1034 | "name": "symfony/polyfill-ctype", 1035 | "version": "v1.27.0", 1036 | "source": { 1037 | "type": "git", 1038 | "url": "https://github.com/symfony/polyfill-ctype.git", 1039 | "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" 1040 | }, 1041 | "dist": { 1042 | "type": "zip", 1043 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", 1044 | "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", 1045 | "shasum": "" 1046 | }, 1047 | "require": { 1048 | "php": ">=7.1" 1049 | }, 1050 | "provide": { 1051 | "ext-ctype": "*" 1052 | }, 1053 | "suggest": { 1054 | "ext-ctype": "For best performance" 1055 | }, 1056 | "type": "library", 1057 | "extra": { 1058 | "branch-alias": { 1059 | "dev-main": "1.27-dev" 1060 | }, 1061 | "thanks": { 1062 | "name": "symfony/polyfill", 1063 | "url": "https://github.com/symfony/polyfill" 1064 | } 1065 | }, 1066 | "autoload": { 1067 | "files": [ 1068 | "bootstrap.php" 1069 | ], 1070 | "psr-4": { 1071 | "Symfony\\Polyfill\\Ctype\\": "" 1072 | } 1073 | }, 1074 | "notification-url": "https://packagist.org/downloads/", 1075 | "license": [ 1076 | "MIT" 1077 | ], 1078 | "authors": [ 1079 | { 1080 | "name": "Gert de Pagter", 1081 | "email": "BackEndTea@gmail.com" 1082 | }, 1083 | { 1084 | "name": "Symfony Community", 1085 | "homepage": "https://symfony.com/contributors" 1086 | } 1087 | ], 1088 | "description": "Symfony polyfill for ctype functions", 1089 | "homepage": "https://symfony.com", 1090 | "keywords": [ 1091 | "compatibility", 1092 | "ctype", 1093 | "polyfill", 1094 | "portable" 1095 | ], 1096 | "support": { 1097 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" 1098 | }, 1099 | "funding": [ 1100 | { 1101 | "url": "https://symfony.com/sponsor", 1102 | "type": "custom" 1103 | }, 1104 | { 1105 | "url": "https://github.com/fabpot", 1106 | "type": "github" 1107 | }, 1108 | { 1109 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1110 | "type": "tidelift" 1111 | } 1112 | ], 1113 | "time": "2022-11-03T14:55:06+00:00" 1114 | }, 1115 | { 1116 | "name": "symfony/polyfill-mbstring", 1117 | "version": "v1.27.0", 1118 | "source": { 1119 | "type": "git", 1120 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1121 | "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" 1122 | }, 1123 | "dist": { 1124 | "type": "zip", 1125 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", 1126 | "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", 1127 | "shasum": "" 1128 | }, 1129 | "require": { 1130 | "php": ">=7.1" 1131 | }, 1132 | "provide": { 1133 | "ext-mbstring": "*" 1134 | }, 1135 | "suggest": { 1136 | "ext-mbstring": "For best performance" 1137 | }, 1138 | "type": "library", 1139 | "extra": { 1140 | "branch-alias": { 1141 | "dev-main": "1.27-dev" 1142 | }, 1143 | "thanks": { 1144 | "name": "symfony/polyfill", 1145 | "url": "https://github.com/symfony/polyfill" 1146 | } 1147 | }, 1148 | "autoload": { 1149 | "files": [ 1150 | "bootstrap.php" 1151 | ], 1152 | "psr-4": { 1153 | "Symfony\\Polyfill\\Mbstring\\": "" 1154 | } 1155 | }, 1156 | "notification-url": "https://packagist.org/downloads/", 1157 | "license": [ 1158 | "MIT" 1159 | ], 1160 | "authors": [ 1161 | { 1162 | "name": "Nicolas Grekas", 1163 | "email": "p@tchwork.com" 1164 | }, 1165 | { 1166 | "name": "Symfony Community", 1167 | "homepage": "https://symfony.com/contributors" 1168 | } 1169 | ], 1170 | "description": "Symfony polyfill for the Mbstring extension", 1171 | "homepage": "https://symfony.com", 1172 | "keywords": [ 1173 | "compatibility", 1174 | "mbstring", 1175 | "polyfill", 1176 | "portable", 1177 | "shim" 1178 | ], 1179 | "support": { 1180 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" 1181 | }, 1182 | "funding": [ 1183 | { 1184 | "url": "https://symfony.com/sponsor", 1185 | "type": "custom" 1186 | }, 1187 | { 1188 | "url": "https://github.com/fabpot", 1189 | "type": "github" 1190 | }, 1191 | { 1192 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1193 | "type": "tidelift" 1194 | } 1195 | ], 1196 | "time": "2022-11-03T14:55:06+00:00" 1197 | }, 1198 | { 1199 | "name": "thecodingmachine/safe", 1200 | "version": "v1.3.3", 1201 | "source": { 1202 | "type": "git", 1203 | "url": "https://github.com/thecodingmachine/safe.git", 1204 | "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc" 1205 | }, 1206 | "dist": { 1207 | "type": "zip", 1208 | "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/a8ab0876305a4cdaef31b2350fcb9811b5608dbc", 1209 | "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc", 1210 | "shasum": "" 1211 | }, 1212 | "require": { 1213 | "php": ">=7.2" 1214 | }, 1215 | "require-dev": { 1216 | "phpstan/phpstan": "^0.12", 1217 | "squizlabs/php_codesniffer": "^3.2", 1218 | "thecodingmachine/phpstan-strict-rules": "^0.12" 1219 | }, 1220 | "type": "library", 1221 | "extra": { 1222 | "branch-alias": { 1223 | "dev-master": "0.1-dev" 1224 | } 1225 | }, 1226 | "autoload": { 1227 | "files": [ 1228 | "deprecated/apc.php", 1229 | "deprecated/libevent.php", 1230 | "deprecated/mssql.php", 1231 | "deprecated/stats.php", 1232 | "lib/special_cases.php", 1233 | "generated/apache.php", 1234 | "generated/apcu.php", 1235 | "generated/array.php", 1236 | "generated/bzip2.php", 1237 | "generated/calendar.php", 1238 | "generated/classobj.php", 1239 | "generated/com.php", 1240 | "generated/cubrid.php", 1241 | "generated/curl.php", 1242 | "generated/datetime.php", 1243 | "generated/dir.php", 1244 | "generated/eio.php", 1245 | "generated/errorfunc.php", 1246 | "generated/exec.php", 1247 | "generated/fileinfo.php", 1248 | "generated/filesystem.php", 1249 | "generated/filter.php", 1250 | "generated/fpm.php", 1251 | "generated/ftp.php", 1252 | "generated/funchand.php", 1253 | "generated/gmp.php", 1254 | "generated/gnupg.php", 1255 | "generated/hash.php", 1256 | "generated/ibase.php", 1257 | "generated/ibmDb2.php", 1258 | "generated/iconv.php", 1259 | "generated/image.php", 1260 | "generated/imap.php", 1261 | "generated/info.php", 1262 | "generated/ingres-ii.php", 1263 | "generated/inotify.php", 1264 | "generated/json.php", 1265 | "generated/ldap.php", 1266 | "generated/libxml.php", 1267 | "generated/lzf.php", 1268 | "generated/mailparse.php", 1269 | "generated/mbstring.php", 1270 | "generated/misc.php", 1271 | "generated/msql.php", 1272 | "generated/mysql.php", 1273 | "generated/mysqli.php", 1274 | "generated/mysqlndMs.php", 1275 | "generated/mysqlndQc.php", 1276 | "generated/network.php", 1277 | "generated/oci8.php", 1278 | "generated/opcache.php", 1279 | "generated/openssl.php", 1280 | "generated/outcontrol.php", 1281 | "generated/password.php", 1282 | "generated/pcntl.php", 1283 | "generated/pcre.php", 1284 | "generated/pdf.php", 1285 | "generated/pgsql.php", 1286 | "generated/posix.php", 1287 | "generated/ps.php", 1288 | "generated/pspell.php", 1289 | "generated/readline.php", 1290 | "generated/rpminfo.php", 1291 | "generated/rrd.php", 1292 | "generated/sem.php", 1293 | "generated/session.php", 1294 | "generated/shmop.php", 1295 | "generated/simplexml.php", 1296 | "generated/sockets.php", 1297 | "generated/sodium.php", 1298 | "generated/solr.php", 1299 | "generated/spl.php", 1300 | "generated/sqlsrv.php", 1301 | "generated/ssdeep.php", 1302 | "generated/ssh2.php", 1303 | "generated/stream.php", 1304 | "generated/strings.php", 1305 | "generated/swoole.php", 1306 | "generated/uodbc.php", 1307 | "generated/uopz.php", 1308 | "generated/url.php", 1309 | "generated/var.php", 1310 | "generated/xdiff.php", 1311 | "generated/xml.php", 1312 | "generated/xmlrpc.php", 1313 | "generated/yaml.php", 1314 | "generated/yaz.php", 1315 | "generated/zip.php", 1316 | "generated/zlib.php" 1317 | ], 1318 | "psr-4": { 1319 | "Safe\\": [ 1320 | "lib/", 1321 | "deprecated/", 1322 | "generated/" 1323 | ] 1324 | } 1325 | }, 1326 | "notification-url": "https://packagist.org/downloads/", 1327 | "license": [ 1328 | "MIT" 1329 | ], 1330 | "description": "PHP core functions that throw exceptions instead of returning FALSE on error", 1331 | "support": { 1332 | "issues": "https://github.com/thecodingmachine/safe/issues", 1333 | "source": "https://github.com/thecodingmachine/safe/tree/v1.3.3" 1334 | }, 1335 | "time": "2020-10-28T17:51:34+00:00" 1336 | }, 1337 | { 1338 | "name": "twig/twig", 1339 | "version": "v3.5.1", 1340 | "source": { 1341 | "type": "git", 1342 | "url": "https://github.com/twigphp/Twig.git", 1343 | "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15" 1344 | }, 1345 | "dist": { 1346 | "type": "zip", 1347 | "url": "https://api.github.com/repos/twigphp/Twig/zipball/a6e0510cc793912b451fd40ab983a1d28f611c15", 1348 | "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15", 1349 | "shasum": "" 1350 | }, 1351 | "require": { 1352 | "php": ">=7.2.5", 1353 | "symfony/polyfill-ctype": "^1.8", 1354 | "symfony/polyfill-mbstring": "^1.3" 1355 | }, 1356 | "require-dev": { 1357 | "psr/container": "^1.0", 1358 | "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" 1359 | }, 1360 | "type": "library", 1361 | "extra": { 1362 | "branch-alias": { 1363 | "dev-master": "3.5-dev" 1364 | } 1365 | }, 1366 | "autoload": { 1367 | "psr-4": { 1368 | "Twig\\": "src/" 1369 | } 1370 | }, 1371 | "notification-url": "https://packagist.org/downloads/", 1372 | "license": [ 1373 | "BSD-3-Clause" 1374 | ], 1375 | "authors": [ 1376 | { 1377 | "name": "Fabien Potencier", 1378 | "email": "fabien@symfony.com", 1379 | "homepage": "http://fabien.potencier.org", 1380 | "role": "Lead Developer" 1381 | }, 1382 | { 1383 | "name": "Twig Team", 1384 | "role": "Contributors" 1385 | }, 1386 | { 1387 | "name": "Armin Ronacher", 1388 | "email": "armin.ronacher@active-4.com", 1389 | "role": "Project Founder" 1390 | } 1391 | ], 1392 | "description": "Twig, the flexible, fast, and secure template language for PHP", 1393 | "homepage": "https://twig.symfony.com", 1394 | "keywords": [ 1395 | "templating" 1396 | ], 1397 | "support": { 1398 | "issues": "https://github.com/twigphp/Twig/issues", 1399 | "source": "https://github.com/twigphp/Twig/tree/v3.5.1" 1400 | }, 1401 | "funding": [ 1402 | { 1403 | "url": "https://github.com/fabpot", 1404 | "type": "github" 1405 | }, 1406 | { 1407 | "url": "https://tidelift.com/funding/github/packagist/twig/twig", 1408 | "type": "tidelift" 1409 | } 1410 | ], 1411 | "time": "2023-02-08T07:49:20+00:00" 1412 | } 1413 | ], 1414 | "packages-dev": [ 1415 | { 1416 | "name": "doctrine/instantiator", 1417 | "version": "2.0.0", 1418 | "source": { 1419 | "type": "git", 1420 | "url": "https://github.com/doctrine/instantiator.git", 1421 | "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" 1422 | }, 1423 | "dist": { 1424 | "type": "zip", 1425 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", 1426 | "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", 1427 | "shasum": "" 1428 | }, 1429 | "require": { 1430 | "php": "^8.1" 1431 | }, 1432 | "require-dev": { 1433 | "doctrine/coding-standard": "^11", 1434 | "ext-pdo": "*", 1435 | "ext-phar": "*", 1436 | "phpbench/phpbench": "^1.2", 1437 | "phpstan/phpstan": "^1.9.4", 1438 | "phpstan/phpstan-phpunit": "^1.3", 1439 | "phpunit/phpunit": "^9.5.27", 1440 | "vimeo/psalm": "^5.4" 1441 | }, 1442 | "type": "library", 1443 | "autoload": { 1444 | "psr-4": { 1445 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 1446 | } 1447 | }, 1448 | "notification-url": "https://packagist.org/downloads/", 1449 | "license": [ 1450 | "MIT" 1451 | ], 1452 | "authors": [ 1453 | { 1454 | "name": "Marco Pivetta", 1455 | "email": "ocramius@gmail.com", 1456 | "homepage": "https://ocramius.github.io/" 1457 | } 1458 | ], 1459 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 1460 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html", 1461 | "keywords": [ 1462 | "constructor", 1463 | "instantiate" 1464 | ], 1465 | "support": { 1466 | "issues": "https://github.com/doctrine/instantiator/issues", 1467 | "source": "https://github.com/doctrine/instantiator/tree/2.0.0" 1468 | }, 1469 | "funding": [ 1470 | { 1471 | "url": "https://www.doctrine-project.org/sponsorship.html", 1472 | "type": "custom" 1473 | }, 1474 | { 1475 | "url": "https://www.patreon.com/phpdoctrine", 1476 | "type": "patreon" 1477 | }, 1478 | { 1479 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", 1480 | "type": "tidelift" 1481 | } 1482 | ], 1483 | "time": "2022-12-30T00:23:10+00:00" 1484 | }, 1485 | { 1486 | "name": "hamcrest/hamcrest-php", 1487 | "version": "v2.0.1", 1488 | "source": { 1489 | "type": "git", 1490 | "url": "https://github.com/hamcrest/hamcrest-php.git", 1491 | "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" 1492 | }, 1493 | "dist": { 1494 | "type": "zip", 1495 | "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", 1496 | "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", 1497 | "shasum": "" 1498 | }, 1499 | "require": { 1500 | "php": "^5.3|^7.0|^8.0" 1501 | }, 1502 | "replace": { 1503 | "cordoval/hamcrest-php": "*", 1504 | "davedevelopment/hamcrest-php": "*", 1505 | "kodova/hamcrest-php": "*" 1506 | }, 1507 | "require-dev": { 1508 | "phpunit/php-file-iterator": "^1.4 || ^2.0", 1509 | "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" 1510 | }, 1511 | "type": "library", 1512 | "extra": { 1513 | "branch-alias": { 1514 | "dev-master": "2.1-dev" 1515 | } 1516 | }, 1517 | "autoload": { 1518 | "classmap": [ 1519 | "hamcrest" 1520 | ] 1521 | }, 1522 | "notification-url": "https://packagist.org/downloads/", 1523 | "license": [ 1524 | "BSD-3-Clause" 1525 | ], 1526 | "description": "This is the PHP port of Hamcrest Matchers", 1527 | "keywords": [ 1528 | "test" 1529 | ], 1530 | "support": { 1531 | "issues": "https://github.com/hamcrest/hamcrest-php/issues", 1532 | "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" 1533 | }, 1534 | "time": "2020-07-09T08:09:16+00:00" 1535 | }, 1536 | { 1537 | "name": "mockery/mockery", 1538 | "version": "1.5.1", 1539 | "source": { 1540 | "type": "git", 1541 | "url": "https://github.com/mockery/mockery.git", 1542 | "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e" 1543 | }, 1544 | "dist": { 1545 | "type": "zip", 1546 | "url": "https://api.github.com/repos/mockery/mockery/zipball/e92dcc83d5a51851baf5f5591d32cb2b16e3684e", 1547 | "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e", 1548 | "shasum": "" 1549 | }, 1550 | "require": { 1551 | "hamcrest/hamcrest-php": "^2.0.1", 1552 | "lib-pcre": ">=7.0", 1553 | "php": "^7.3 || ^8.0" 1554 | }, 1555 | "conflict": { 1556 | "phpunit/phpunit": "<8.0" 1557 | }, 1558 | "require-dev": { 1559 | "phpunit/phpunit": "^8.5 || ^9.3" 1560 | }, 1561 | "type": "library", 1562 | "extra": { 1563 | "branch-alias": { 1564 | "dev-master": "1.4.x-dev" 1565 | } 1566 | }, 1567 | "autoload": { 1568 | "psr-0": { 1569 | "Mockery": "library/" 1570 | } 1571 | }, 1572 | "notification-url": "https://packagist.org/downloads/", 1573 | "license": [ 1574 | "BSD-3-Clause" 1575 | ], 1576 | "authors": [ 1577 | { 1578 | "name": "Pádraic Brady", 1579 | "email": "padraic.brady@gmail.com", 1580 | "homepage": "http://blog.astrumfutura.com" 1581 | }, 1582 | { 1583 | "name": "Dave Marshall", 1584 | "email": "dave.marshall@atstsolutions.co.uk", 1585 | "homepage": "http://davedevelopment.co.uk" 1586 | } 1587 | ], 1588 | "description": "Mockery is a simple yet flexible PHP mock object framework", 1589 | "homepage": "https://github.com/mockery/mockery", 1590 | "keywords": [ 1591 | "BDD", 1592 | "TDD", 1593 | "library", 1594 | "mock", 1595 | "mock objects", 1596 | "mockery", 1597 | "stub", 1598 | "test", 1599 | "test double", 1600 | "testing" 1601 | ], 1602 | "support": { 1603 | "issues": "https://github.com/mockery/mockery/issues", 1604 | "source": "https://github.com/mockery/mockery/tree/1.5.1" 1605 | }, 1606 | "time": "2022-09-07T15:32:08+00:00" 1607 | }, 1608 | { 1609 | "name": "myclabs/deep-copy", 1610 | "version": "1.11.0", 1611 | "source": { 1612 | "type": "git", 1613 | "url": "https://github.com/myclabs/DeepCopy.git", 1614 | "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" 1615 | }, 1616 | "dist": { 1617 | "type": "zip", 1618 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", 1619 | "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", 1620 | "shasum": "" 1621 | }, 1622 | "require": { 1623 | "php": "^7.1 || ^8.0" 1624 | }, 1625 | "conflict": { 1626 | "doctrine/collections": "<1.6.8", 1627 | "doctrine/common": "<2.13.3 || >=3,<3.2.2" 1628 | }, 1629 | "require-dev": { 1630 | "doctrine/collections": "^1.6.8", 1631 | "doctrine/common": "^2.13.3 || ^3.2.2", 1632 | "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" 1633 | }, 1634 | "type": "library", 1635 | "autoload": { 1636 | "files": [ 1637 | "src/DeepCopy/deep_copy.php" 1638 | ], 1639 | "psr-4": { 1640 | "DeepCopy\\": "src/DeepCopy/" 1641 | } 1642 | }, 1643 | "notification-url": "https://packagist.org/downloads/", 1644 | "license": [ 1645 | "MIT" 1646 | ], 1647 | "description": "Create deep copies (clones) of your objects", 1648 | "keywords": [ 1649 | "clone", 1650 | "copy", 1651 | "duplicate", 1652 | "object", 1653 | "object graph" 1654 | ], 1655 | "support": { 1656 | "issues": "https://github.com/myclabs/DeepCopy/issues", 1657 | "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" 1658 | }, 1659 | "funding": [ 1660 | { 1661 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", 1662 | "type": "tidelift" 1663 | } 1664 | ], 1665 | "time": "2022-03-03T13:19:32+00:00" 1666 | }, 1667 | { 1668 | "name": "nikic/php-parser", 1669 | "version": "v4.15.3", 1670 | "source": { 1671 | "type": "git", 1672 | "url": "https://github.com/nikic/PHP-Parser.git", 1673 | "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039" 1674 | }, 1675 | "dist": { 1676 | "type": "zip", 1677 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/570e980a201d8ed0236b0a62ddf2c9cbb2034039", 1678 | "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039", 1679 | "shasum": "" 1680 | }, 1681 | "require": { 1682 | "ext-tokenizer": "*", 1683 | "php": ">=7.0" 1684 | }, 1685 | "require-dev": { 1686 | "ircmaxell/php-yacc": "^0.0.7", 1687 | "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" 1688 | }, 1689 | "bin": [ 1690 | "bin/php-parse" 1691 | ], 1692 | "type": "library", 1693 | "extra": { 1694 | "branch-alias": { 1695 | "dev-master": "4.9-dev" 1696 | } 1697 | }, 1698 | "autoload": { 1699 | "psr-4": { 1700 | "PhpParser\\": "lib/PhpParser" 1701 | } 1702 | }, 1703 | "notification-url": "https://packagist.org/downloads/", 1704 | "license": [ 1705 | "BSD-3-Clause" 1706 | ], 1707 | "authors": [ 1708 | { 1709 | "name": "Nikita Popov" 1710 | } 1711 | ], 1712 | "description": "A PHP parser written in PHP", 1713 | "keywords": [ 1714 | "parser", 1715 | "php" 1716 | ], 1717 | "support": { 1718 | "issues": "https://github.com/nikic/PHP-Parser/issues", 1719 | "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.3" 1720 | }, 1721 | "time": "2023-01-16T22:05:37+00:00" 1722 | }, 1723 | { 1724 | "name": "phar-io/manifest", 1725 | "version": "2.0.3", 1726 | "source": { 1727 | "type": "git", 1728 | "url": "https://github.com/phar-io/manifest.git", 1729 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53" 1730 | }, 1731 | "dist": { 1732 | "type": "zip", 1733 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", 1734 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53", 1735 | "shasum": "" 1736 | }, 1737 | "require": { 1738 | "ext-dom": "*", 1739 | "ext-phar": "*", 1740 | "ext-xmlwriter": "*", 1741 | "phar-io/version": "^3.0.1", 1742 | "php": "^7.2 || ^8.0" 1743 | }, 1744 | "type": "library", 1745 | "extra": { 1746 | "branch-alias": { 1747 | "dev-master": "2.0.x-dev" 1748 | } 1749 | }, 1750 | "autoload": { 1751 | "classmap": [ 1752 | "src/" 1753 | ] 1754 | }, 1755 | "notification-url": "https://packagist.org/downloads/", 1756 | "license": [ 1757 | "BSD-3-Clause" 1758 | ], 1759 | "authors": [ 1760 | { 1761 | "name": "Arne Blankerts", 1762 | "email": "arne@blankerts.de", 1763 | "role": "Developer" 1764 | }, 1765 | { 1766 | "name": "Sebastian Heuer", 1767 | "email": "sebastian@phpeople.de", 1768 | "role": "Developer" 1769 | }, 1770 | { 1771 | "name": "Sebastian Bergmann", 1772 | "email": "sebastian@phpunit.de", 1773 | "role": "Developer" 1774 | } 1775 | ], 1776 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 1777 | "support": { 1778 | "issues": "https://github.com/phar-io/manifest/issues", 1779 | "source": "https://github.com/phar-io/manifest/tree/2.0.3" 1780 | }, 1781 | "time": "2021-07-20T11:28:43+00:00" 1782 | }, 1783 | { 1784 | "name": "phar-io/version", 1785 | "version": "3.2.1", 1786 | "source": { 1787 | "type": "git", 1788 | "url": "https://github.com/phar-io/version.git", 1789 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" 1790 | }, 1791 | "dist": { 1792 | "type": "zip", 1793 | "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", 1794 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", 1795 | "shasum": "" 1796 | }, 1797 | "require": { 1798 | "php": "^7.2 || ^8.0" 1799 | }, 1800 | "type": "library", 1801 | "autoload": { 1802 | "classmap": [ 1803 | "src/" 1804 | ] 1805 | }, 1806 | "notification-url": "https://packagist.org/downloads/", 1807 | "license": [ 1808 | "BSD-3-Clause" 1809 | ], 1810 | "authors": [ 1811 | { 1812 | "name": "Arne Blankerts", 1813 | "email": "arne@blankerts.de", 1814 | "role": "Developer" 1815 | }, 1816 | { 1817 | "name": "Sebastian Heuer", 1818 | "email": "sebastian@phpeople.de", 1819 | "role": "Developer" 1820 | }, 1821 | { 1822 | "name": "Sebastian Bergmann", 1823 | "email": "sebastian@phpunit.de", 1824 | "role": "Developer" 1825 | } 1826 | ], 1827 | "description": "Library for handling version information and constraints", 1828 | "support": { 1829 | "issues": "https://github.com/phar-io/version/issues", 1830 | "source": "https://github.com/phar-io/version/tree/3.2.1" 1831 | }, 1832 | "time": "2022-02-21T01:04:05+00:00" 1833 | }, 1834 | { 1835 | "name": "phpunit/php-code-coverage", 1836 | "version": "9.2.25", 1837 | "source": { 1838 | "type": "git", 1839 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 1840 | "reference": "0e2b40518197a8c0d4b08bc34dfff1c99c508954" 1841 | }, 1842 | "dist": { 1843 | "type": "zip", 1844 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0e2b40518197a8c0d4b08bc34dfff1c99c508954", 1845 | "reference": "0e2b40518197a8c0d4b08bc34dfff1c99c508954", 1846 | "shasum": "" 1847 | }, 1848 | "require": { 1849 | "ext-dom": "*", 1850 | "ext-libxml": "*", 1851 | "ext-xmlwriter": "*", 1852 | "nikic/php-parser": "^4.15", 1853 | "php": ">=7.3", 1854 | "phpunit/php-file-iterator": "^3.0.3", 1855 | "phpunit/php-text-template": "^2.0.2", 1856 | "sebastian/code-unit-reverse-lookup": "^2.0.2", 1857 | "sebastian/complexity": "^2.0", 1858 | "sebastian/environment": "^5.1.2", 1859 | "sebastian/lines-of-code": "^1.0.3", 1860 | "sebastian/version": "^3.0.1", 1861 | "theseer/tokenizer": "^1.2.0" 1862 | }, 1863 | "require-dev": { 1864 | "phpunit/phpunit": "^9.3" 1865 | }, 1866 | "suggest": { 1867 | "ext-pcov": "*", 1868 | "ext-xdebug": "*" 1869 | }, 1870 | "type": "library", 1871 | "extra": { 1872 | "branch-alias": { 1873 | "dev-master": "9.2-dev" 1874 | } 1875 | }, 1876 | "autoload": { 1877 | "classmap": [ 1878 | "src/" 1879 | ] 1880 | }, 1881 | "notification-url": "https://packagist.org/downloads/", 1882 | "license": [ 1883 | "BSD-3-Clause" 1884 | ], 1885 | "authors": [ 1886 | { 1887 | "name": "Sebastian Bergmann", 1888 | "email": "sebastian@phpunit.de", 1889 | "role": "lead" 1890 | } 1891 | ], 1892 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 1893 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 1894 | "keywords": [ 1895 | "coverage", 1896 | "testing", 1897 | "xunit" 1898 | ], 1899 | "support": { 1900 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", 1901 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.25" 1902 | }, 1903 | "funding": [ 1904 | { 1905 | "url": "https://github.com/sebastianbergmann", 1906 | "type": "github" 1907 | } 1908 | ], 1909 | "time": "2023-02-25T05:32:00+00:00" 1910 | }, 1911 | { 1912 | "name": "phpunit/php-file-iterator", 1913 | "version": "3.0.6", 1914 | "source": { 1915 | "type": "git", 1916 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 1917 | "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" 1918 | }, 1919 | "dist": { 1920 | "type": "zip", 1921 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", 1922 | "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", 1923 | "shasum": "" 1924 | }, 1925 | "require": { 1926 | "php": ">=7.3" 1927 | }, 1928 | "require-dev": { 1929 | "phpunit/phpunit": "^9.3" 1930 | }, 1931 | "type": "library", 1932 | "extra": { 1933 | "branch-alias": { 1934 | "dev-master": "3.0-dev" 1935 | } 1936 | }, 1937 | "autoload": { 1938 | "classmap": [ 1939 | "src/" 1940 | ] 1941 | }, 1942 | "notification-url": "https://packagist.org/downloads/", 1943 | "license": [ 1944 | "BSD-3-Clause" 1945 | ], 1946 | "authors": [ 1947 | { 1948 | "name": "Sebastian Bergmann", 1949 | "email": "sebastian@phpunit.de", 1950 | "role": "lead" 1951 | } 1952 | ], 1953 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 1954 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 1955 | "keywords": [ 1956 | "filesystem", 1957 | "iterator" 1958 | ], 1959 | "support": { 1960 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", 1961 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" 1962 | }, 1963 | "funding": [ 1964 | { 1965 | "url": "https://github.com/sebastianbergmann", 1966 | "type": "github" 1967 | } 1968 | ], 1969 | "time": "2021-12-02T12:48:52+00:00" 1970 | }, 1971 | { 1972 | "name": "phpunit/php-invoker", 1973 | "version": "3.1.1", 1974 | "source": { 1975 | "type": "git", 1976 | "url": "https://github.com/sebastianbergmann/php-invoker.git", 1977 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" 1978 | }, 1979 | "dist": { 1980 | "type": "zip", 1981 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", 1982 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", 1983 | "shasum": "" 1984 | }, 1985 | "require": { 1986 | "php": ">=7.3" 1987 | }, 1988 | "require-dev": { 1989 | "ext-pcntl": "*", 1990 | "phpunit/phpunit": "^9.3" 1991 | }, 1992 | "suggest": { 1993 | "ext-pcntl": "*" 1994 | }, 1995 | "type": "library", 1996 | "extra": { 1997 | "branch-alias": { 1998 | "dev-master": "3.1-dev" 1999 | } 2000 | }, 2001 | "autoload": { 2002 | "classmap": [ 2003 | "src/" 2004 | ] 2005 | }, 2006 | "notification-url": "https://packagist.org/downloads/", 2007 | "license": [ 2008 | "BSD-3-Clause" 2009 | ], 2010 | "authors": [ 2011 | { 2012 | "name": "Sebastian Bergmann", 2013 | "email": "sebastian@phpunit.de", 2014 | "role": "lead" 2015 | } 2016 | ], 2017 | "description": "Invoke callables with a timeout", 2018 | "homepage": "https://github.com/sebastianbergmann/php-invoker/", 2019 | "keywords": [ 2020 | "process" 2021 | ], 2022 | "support": { 2023 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues", 2024 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" 2025 | }, 2026 | "funding": [ 2027 | { 2028 | "url": "https://github.com/sebastianbergmann", 2029 | "type": "github" 2030 | } 2031 | ], 2032 | "time": "2020-09-28T05:58:55+00:00" 2033 | }, 2034 | { 2035 | "name": "phpunit/php-text-template", 2036 | "version": "2.0.4", 2037 | "source": { 2038 | "type": "git", 2039 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 2040 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" 2041 | }, 2042 | "dist": { 2043 | "type": "zip", 2044 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", 2045 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", 2046 | "shasum": "" 2047 | }, 2048 | "require": { 2049 | "php": ">=7.3" 2050 | }, 2051 | "require-dev": { 2052 | "phpunit/phpunit": "^9.3" 2053 | }, 2054 | "type": "library", 2055 | "extra": { 2056 | "branch-alias": { 2057 | "dev-master": "2.0-dev" 2058 | } 2059 | }, 2060 | "autoload": { 2061 | "classmap": [ 2062 | "src/" 2063 | ] 2064 | }, 2065 | "notification-url": "https://packagist.org/downloads/", 2066 | "license": [ 2067 | "BSD-3-Clause" 2068 | ], 2069 | "authors": [ 2070 | { 2071 | "name": "Sebastian Bergmann", 2072 | "email": "sebastian@phpunit.de", 2073 | "role": "lead" 2074 | } 2075 | ], 2076 | "description": "Simple template engine.", 2077 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 2078 | "keywords": [ 2079 | "template" 2080 | ], 2081 | "support": { 2082 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues", 2083 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" 2084 | }, 2085 | "funding": [ 2086 | { 2087 | "url": "https://github.com/sebastianbergmann", 2088 | "type": "github" 2089 | } 2090 | ], 2091 | "time": "2020-10-26T05:33:50+00:00" 2092 | }, 2093 | { 2094 | "name": "phpunit/php-timer", 2095 | "version": "5.0.3", 2096 | "source": { 2097 | "type": "git", 2098 | "url": "https://github.com/sebastianbergmann/php-timer.git", 2099 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" 2100 | }, 2101 | "dist": { 2102 | "type": "zip", 2103 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", 2104 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", 2105 | "shasum": "" 2106 | }, 2107 | "require": { 2108 | "php": ">=7.3" 2109 | }, 2110 | "require-dev": { 2111 | "phpunit/phpunit": "^9.3" 2112 | }, 2113 | "type": "library", 2114 | "extra": { 2115 | "branch-alias": { 2116 | "dev-master": "5.0-dev" 2117 | } 2118 | }, 2119 | "autoload": { 2120 | "classmap": [ 2121 | "src/" 2122 | ] 2123 | }, 2124 | "notification-url": "https://packagist.org/downloads/", 2125 | "license": [ 2126 | "BSD-3-Clause" 2127 | ], 2128 | "authors": [ 2129 | { 2130 | "name": "Sebastian Bergmann", 2131 | "email": "sebastian@phpunit.de", 2132 | "role": "lead" 2133 | } 2134 | ], 2135 | "description": "Utility class for timing", 2136 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 2137 | "keywords": [ 2138 | "timer" 2139 | ], 2140 | "support": { 2141 | "issues": "https://github.com/sebastianbergmann/php-timer/issues", 2142 | "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" 2143 | }, 2144 | "funding": [ 2145 | { 2146 | "url": "https://github.com/sebastianbergmann", 2147 | "type": "github" 2148 | } 2149 | ], 2150 | "time": "2020-10-26T13:16:10+00:00" 2151 | }, 2152 | { 2153 | "name": "phpunit/phpunit", 2154 | "version": "9.6.3", 2155 | "source": { 2156 | "type": "git", 2157 | "url": "https://github.com/sebastianbergmann/phpunit.git", 2158 | "reference": "e7b1615e3e887d6c719121c6d4a44b0ab9645555" 2159 | }, 2160 | "dist": { 2161 | "type": "zip", 2162 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e7b1615e3e887d6c719121c6d4a44b0ab9645555", 2163 | "reference": "e7b1615e3e887d6c719121c6d4a44b0ab9645555", 2164 | "shasum": "" 2165 | }, 2166 | "require": { 2167 | "doctrine/instantiator": "^1.3.1 || ^2", 2168 | "ext-dom": "*", 2169 | "ext-json": "*", 2170 | "ext-libxml": "*", 2171 | "ext-mbstring": "*", 2172 | "ext-xml": "*", 2173 | "ext-xmlwriter": "*", 2174 | "myclabs/deep-copy": "^1.10.1", 2175 | "phar-io/manifest": "^2.0.3", 2176 | "phar-io/version": "^3.0.2", 2177 | "php": ">=7.3", 2178 | "phpunit/php-code-coverage": "^9.2.13", 2179 | "phpunit/php-file-iterator": "^3.0.5", 2180 | "phpunit/php-invoker": "^3.1.1", 2181 | "phpunit/php-text-template": "^2.0.3", 2182 | "phpunit/php-timer": "^5.0.2", 2183 | "sebastian/cli-parser": "^1.0.1", 2184 | "sebastian/code-unit": "^1.0.6", 2185 | "sebastian/comparator": "^4.0.8", 2186 | "sebastian/diff": "^4.0.3", 2187 | "sebastian/environment": "^5.1.3", 2188 | "sebastian/exporter": "^4.0.5", 2189 | "sebastian/global-state": "^5.0.1", 2190 | "sebastian/object-enumerator": "^4.0.3", 2191 | "sebastian/resource-operations": "^3.0.3", 2192 | "sebastian/type": "^3.2", 2193 | "sebastian/version": "^3.0.2" 2194 | }, 2195 | "suggest": { 2196 | "ext-soap": "*", 2197 | "ext-xdebug": "*" 2198 | }, 2199 | "bin": [ 2200 | "phpunit" 2201 | ], 2202 | "type": "library", 2203 | "extra": { 2204 | "branch-alias": { 2205 | "dev-master": "9.6-dev" 2206 | } 2207 | }, 2208 | "autoload": { 2209 | "files": [ 2210 | "src/Framework/Assert/Functions.php" 2211 | ], 2212 | "classmap": [ 2213 | "src/" 2214 | ] 2215 | }, 2216 | "notification-url": "https://packagist.org/downloads/", 2217 | "license": [ 2218 | "BSD-3-Clause" 2219 | ], 2220 | "authors": [ 2221 | { 2222 | "name": "Sebastian Bergmann", 2223 | "email": "sebastian@phpunit.de", 2224 | "role": "lead" 2225 | } 2226 | ], 2227 | "description": "The PHP Unit Testing framework.", 2228 | "homepage": "https://phpunit.de/", 2229 | "keywords": [ 2230 | "phpunit", 2231 | "testing", 2232 | "xunit" 2233 | ], 2234 | "support": { 2235 | "issues": "https://github.com/sebastianbergmann/phpunit/issues", 2236 | "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.3" 2237 | }, 2238 | "funding": [ 2239 | { 2240 | "url": "https://phpunit.de/sponsors.html", 2241 | "type": "custom" 2242 | }, 2243 | { 2244 | "url": "https://github.com/sebastianbergmann", 2245 | "type": "github" 2246 | }, 2247 | { 2248 | "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", 2249 | "type": "tidelift" 2250 | } 2251 | ], 2252 | "time": "2023-02-04T13:37:15+00:00" 2253 | }, 2254 | { 2255 | "name": "psr/log", 2256 | "version": "3.0.0", 2257 | "source": { 2258 | "type": "git", 2259 | "url": "https://github.com/php-fig/log.git", 2260 | "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" 2261 | }, 2262 | "dist": { 2263 | "type": "zip", 2264 | "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", 2265 | "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", 2266 | "shasum": "" 2267 | }, 2268 | "require": { 2269 | "php": ">=8.0.0" 2270 | }, 2271 | "type": "library", 2272 | "extra": { 2273 | "branch-alias": { 2274 | "dev-master": "3.x-dev" 2275 | } 2276 | }, 2277 | "autoload": { 2278 | "psr-4": { 2279 | "Psr\\Log\\": "src" 2280 | } 2281 | }, 2282 | "notification-url": "https://packagist.org/downloads/", 2283 | "license": [ 2284 | "MIT" 2285 | ], 2286 | "authors": [ 2287 | { 2288 | "name": "PHP-FIG", 2289 | "homepage": "https://www.php-fig.org/" 2290 | } 2291 | ], 2292 | "description": "Common interface for logging libraries", 2293 | "homepage": "https://github.com/php-fig/log", 2294 | "keywords": [ 2295 | "log", 2296 | "psr", 2297 | "psr-3" 2298 | ], 2299 | "support": { 2300 | "source": "https://github.com/php-fig/log/tree/3.0.0" 2301 | }, 2302 | "time": "2021-07-14T16:46:02+00:00" 2303 | }, 2304 | { 2305 | "name": "sebastian/cli-parser", 2306 | "version": "1.0.1", 2307 | "source": { 2308 | "type": "git", 2309 | "url": "https://github.com/sebastianbergmann/cli-parser.git", 2310 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" 2311 | }, 2312 | "dist": { 2313 | "type": "zip", 2314 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", 2315 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", 2316 | "shasum": "" 2317 | }, 2318 | "require": { 2319 | "php": ">=7.3" 2320 | }, 2321 | "require-dev": { 2322 | "phpunit/phpunit": "^9.3" 2323 | }, 2324 | "type": "library", 2325 | "extra": { 2326 | "branch-alias": { 2327 | "dev-master": "1.0-dev" 2328 | } 2329 | }, 2330 | "autoload": { 2331 | "classmap": [ 2332 | "src/" 2333 | ] 2334 | }, 2335 | "notification-url": "https://packagist.org/downloads/", 2336 | "license": [ 2337 | "BSD-3-Clause" 2338 | ], 2339 | "authors": [ 2340 | { 2341 | "name": "Sebastian Bergmann", 2342 | "email": "sebastian@phpunit.de", 2343 | "role": "lead" 2344 | } 2345 | ], 2346 | "description": "Library for parsing CLI options", 2347 | "homepage": "https://github.com/sebastianbergmann/cli-parser", 2348 | "support": { 2349 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues", 2350 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" 2351 | }, 2352 | "funding": [ 2353 | { 2354 | "url": "https://github.com/sebastianbergmann", 2355 | "type": "github" 2356 | } 2357 | ], 2358 | "time": "2020-09-28T06:08:49+00:00" 2359 | }, 2360 | { 2361 | "name": "sebastian/code-unit", 2362 | "version": "1.0.8", 2363 | "source": { 2364 | "type": "git", 2365 | "url": "https://github.com/sebastianbergmann/code-unit.git", 2366 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" 2367 | }, 2368 | "dist": { 2369 | "type": "zip", 2370 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", 2371 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", 2372 | "shasum": "" 2373 | }, 2374 | "require": { 2375 | "php": ">=7.3" 2376 | }, 2377 | "require-dev": { 2378 | "phpunit/phpunit": "^9.3" 2379 | }, 2380 | "type": "library", 2381 | "extra": { 2382 | "branch-alias": { 2383 | "dev-master": "1.0-dev" 2384 | } 2385 | }, 2386 | "autoload": { 2387 | "classmap": [ 2388 | "src/" 2389 | ] 2390 | }, 2391 | "notification-url": "https://packagist.org/downloads/", 2392 | "license": [ 2393 | "BSD-3-Clause" 2394 | ], 2395 | "authors": [ 2396 | { 2397 | "name": "Sebastian Bergmann", 2398 | "email": "sebastian@phpunit.de", 2399 | "role": "lead" 2400 | } 2401 | ], 2402 | "description": "Collection of value objects that represent the PHP code units", 2403 | "homepage": "https://github.com/sebastianbergmann/code-unit", 2404 | "support": { 2405 | "issues": "https://github.com/sebastianbergmann/code-unit/issues", 2406 | "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" 2407 | }, 2408 | "funding": [ 2409 | { 2410 | "url": "https://github.com/sebastianbergmann", 2411 | "type": "github" 2412 | } 2413 | ], 2414 | "time": "2020-10-26T13:08:54+00:00" 2415 | }, 2416 | { 2417 | "name": "sebastian/code-unit-reverse-lookup", 2418 | "version": "2.0.3", 2419 | "source": { 2420 | "type": "git", 2421 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 2422 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" 2423 | }, 2424 | "dist": { 2425 | "type": "zip", 2426 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 2427 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 2428 | "shasum": "" 2429 | }, 2430 | "require": { 2431 | "php": ">=7.3" 2432 | }, 2433 | "require-dev": { 2434 | "phpunit/phpunit": "^9.3" 2435 | }, 2436 | "type": "library", 2437 | "extra": { 2438 | "branch-alias": { 2439 | "dev-master": "2.0-dev" 2440 | } 2441 | }, 2442 | "autoload": { 2443 | "classmap": [ 2444 | "src/" 2445 | ] 2446 | }, 2447 | "notification-url": "https://packagist.org/downloads/", 2448 | "license": [ 2449 | "BSD-3-Clause" 2450 | ], 2451 | "authors": [ 2452 | { 2453 | "name": "Sebastian Bergmann", 2454 | "email": "sebastian@phpunit.de" 2455 | } 2456 | ], 2457 | "description": "Looks up which function or method a line of code belongs to", 2458 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 2459 | "support": { 2460 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", 2461 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" 2462 | }, 2463 | "funding": [ 2464 | { 2465 | "url": "https://github.com/sebastianbergmann", 2466 | "type": "github" 2467 | } 2468 | ], 2469 | "time": "2020-09-28T05:30:19+00:00" 2470 | }, 2471 | { 2472 | "name": "sebastian/comparator", 2473 | "version": "4.0.8", 2474 | "source": { 2475 | "type": "git", 2476 | "url": "https://github.com/sebastianbergmann/comparator.git", 2477 | "reference": "fa0f136dd2334583309d32b62544682ee972b51a" 2478 | }, 2479 | "dist": { 2480 | "type": "zip", 2481 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", 2482 | "reference": "fa0f136dd2334583309d32b62544682ee972b51a", 2483 | "shasum": "" 2484 | }, 2485 | "require": { 2486 | "php": ">=7.3", 2487 | "sebastian/diff": "^4.0", 2488 | "sebastian/exporter": "^4.0" 2489 | }, 2490 | "require-dev": { 2491 | "phpunit/phpunit": "^9.3" 2492 | }, 2493 | "type": "library", 2494 | "extra": { 2495 | "branch-alias": { 2496 | "dev-master": "4.0-dev" 2497 | } 2498 | }, 2499 | "autoload": { 2500 | "classmap": [ 2501 | "src/" 2502 | ] 2503 | }, 2504 | "notification-url": "https://packagist.org/downloads/", 2505 | "license": [ 2506 | "BSD-3-Clause" 2507 | ], 2508 | "authors": [ 2509 | { 2510 | "name": "Sebastian Bergmann", 2511 | "email": "sebastian@phpunit.de" 2512 | }, 2513 | { 2514 | "name": "Jeff Welch", 2515 | "email": "whatthejeff@gmail.com" 2516 | }, 2517 | { 2518 | "name": "Volker Dusch", 2519 | "email": "github@wallbash.com" 2520 | }, 2521 | { 2522 | "name": "Bernhard Schussek", 2523 | "email": "bschussek@2bepublished.at" 2524 | } 2525 | ], 2526 | "description": "Provides the functionality to compare PHP values for equality", 2527 | "homepage": "https://github.com/sebastianbergmann/comparator", 2528 | "keywords": [ 2529 | "comparator", 2530 | "compare", 2531 | "equality" 2532 | ], 2533 | "support": { 2534 | "issues": "https://github.com/sebastianbergmann/comparator/issues", 2535 | "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" 2536 | }, 2537 | "funding": [ 2538 | { 2539 | "url": "https://github.com/sebastianbergmann", 2540 | "type": "github" 2541 | } 2542 | ], 2543 | "time": "2022-09-14T12:41:17+00:00" 2544 | }, 2545 | { 2546 | "name": "sebastian/complexity", 2547 | "version": "2.0.2", 2548 | "source": { 2549 | "type": "git", 2550 | "url": "https://github.com/sebastianbergmann/complexity.git", 2551 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" 2552 | }, 2553 | "dist": { 2554 | "type": "zip", 2555 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", 2556 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", 2557 | "shasum": "" 2558 | }, 2559 | "require": { 2560 | "nikic/php-parser": "^4.7", 2561 | "php": ">=7.3" 2562 | }, 2563 | "require-dev": { 2564 | "phpunit/phpunit": "^9.3" 2565 | }, 2566 | "type": "library", 2567 | "extra": { 2568 | "branch-alias": { 2569 | "dev-master": "2.0-dev" 2570 | } 2571 | }, 2572 | "autoload": { 2573 | "classmap": [ 2574 | "src/" 2575 | ] 2576 | }, 2577 | "notification-url": "https://packagist.org/downloads/", 2578 | "license": [ 2579 | "BSD-3-Clause" 2580 | ], 2581 | "authors": [ 2582 | { 2583 | "name": "Sebastian Bergmann", 2584 | "email": "sebastian@phpunit.de", 2585 | "role": "lead" 2586 | } 2587 | ], 2588 | "description": "Library for calculating the complexity of PHP code units", 2589 | "homepage": "https://github.com/sebastianbergmann/complexity", 2590 | "support": { 2591 | "issues": "https://github.com/sebastianbergmann/complexity/issues", 2592 | "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" 2593 | }, 2594 | "funding": [ 2595 | { 2596 | "url": "https://github.com/sebastianbergmann", 2597 | "type": "github" 2598 | } 2599 | ], 2600 | "time": "2020-10-26T15:52:27+00:00" 2601 | }, 2602 | { 2603 | "name": "sebastian/diff", 2604 | "version": "4.0.4", 2605 | "source": { 2606 | "type": "git", 2607 | "url": "https://github.com/sebastianbergmann/diff.git", 2608 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" 2609 | }, 2610 | "dist": { 2611 | "type": "zip", 2612 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", 2613 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", 2614 | "shasum": "" 2615 | }, 2616 | "require": { 2617 | "php": ">=7.3" 2618 | }, 2619 | "require-dev": { 2620 | "phpunit/phpunit": "^9.3", 2621 | "symfony/process": "^4.2 || ^5" 2622 | }, 2623 | "type": "library", 2624 | "extra": { 2625 | "branch-alias": { 2626 | "dev-master": "4.0-dev" 2627 | } 2628 | }, 2629 | "autoload": { 2630 | "classmap": [ 2631 | "src/" 2632 | ] 2633 | }, 2634 | "notification-url": "https://packagist.org/downloads/", 2635 | "license": [ 2636 | "BSD-3-Clause" 2637 | ], 2638 | "authors": [ 2639 | { 2640 | "name": "Sebastian Bergmann", 2641 | "email": "sebastian@phpunit.de" 2642 | }, 2643 | { 2644 | "name": "Kore Nordmann", 2645 | "email": "mail@kore-nordmann.de" 2646 | } 2647 | ], 2648 | "description": "Diff implementation", 2649 | "homepage": "https://github.com/sebastianbergmann/diff", 2650 | "keywords": [ 2651 | "diff", 2652 | "udiff", 2653 | "unidiff", 2654 | "unified diff" 2655 | ], 2656 | "support": { 2657 | "issues": "https://github.com/sebastianbergmann/diff/issues", 2658 | "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" 2659 | }, 2660 | "funding": [ 2661 | { 2662 | "url": "https://github.com/sebastianbergmann", 2663 | "type": "github" 2664 | } 2665 | ], 2666 | "time": "2020-10-26T13:10:38+00:00" 2667 | }, 2668 | { 2669 | "name": "sebastian/environment", 2670 | "version": "5.1.5", 2671 | "source": { 2672 | "type": "git", 2673 | "url": "https://github.com/sebastianbergmann/environment.git", 2674 | "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" 2675 | }, 2676 | "dist": { 2677 | "type": "zip", 2678 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", 2679 | "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", 2680 | "shasum": "" 2681 | }, 2682 | "require": { 2683 | "php": ">=7.3" 2684 | }, 2685 | "require-dev": { 2686 | "phpunit/phpunit": "^9.3" 2687 | }, 2688 | "suggest": { 2689 | "ext-posix": "*" 2690 | }, 2691 | "type": "library", 2692 | "extra": { 2693 | "branch-alias": { 2694 | "dev-master": "5.1-dev" 2695 | } 2696 | }, 2697 | "autoload": { 2698 | "classmap": [ 2699 | "src/" 2700 | ] 2701 | }, 2702 | "notification-url": "https://packagist.org/downloads/", 2703 | "license": [ 2704 | "BSD-3-Clause" 2705 | ], 2706 | "authors": [ 2707 | { 2708 | "name": "Sebastian Bergmann", 2709 | "email": "sebastian@phpunit.de" 2710 | } 2711 | ], 2712 | "description": "Provides functionality to handle HHVM/PHP environments", 2713 | "homepage": "http://www.github.com/sebastianbergmann/environment", 2714 | "keywords": [ 2715 | "Xdebug", 2716 | "environment", 2717 | "hhvm" 2718 | ], 2719 | "support": { 2720 | "issues": "https://github.com/sebastianbergmann/environment/issues", 2721 | "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" 2722 | }, 2723 | "funding": [ 2724 | { 2725 | "url": "https://github.com/sebastianbergmann", 2726 | "type": "github" 2727 | } 2728 | ], 2729 | "time": "2023-02-03T06:03:51+00:00" 2730 | }, 2731 | { 2732 | "name": "sebastian/exporter", 2733 | "version": "4.0.5", 2734 | "source": { 2735 | "type": "git", 2736 | "url": "https://github.com/sebastianbergmann/exporter.git", 2737 | "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" 2738 | }, 2739 | "dist": { 2740 | "type": "zip", 2741 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", 2742 | "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", 2743 | "shasum": "" 2744 | }, 2745 | "require": { 2746 | "php": ">=7.3", 2747 | "sebastian/recursion-context": "^4.0" 2748 | }, 2749 | "require-dev": { 2750 | "ext-mbstring": "*", 2751 | "phpunit/phpunit": "^9.3" 2752 | }, 2753 | "type": "library", 2754 | "extra": { 2755 | "branch-alias": { 2756 | "dev-master": "4.0-dev" 2757 | } 2758 | }, 2759 | "autoload": { 2760 | "classmap": [ 2761 | "src/" 2762 | ] 2763 | }, 2764 | "notification-url": "https://packagist.org/downloads/", 2765 | "license": [ 2766 | "BSD-3-Clause" 2767 | ], 2768 | "authors": [ 2769 | { 2770 | "name": "Sebastian Bergmann", 2771 | "email": "sebastian@phpunit.de" 2772 | }, 2773 | { 2774 | "name": "Jeff Welch", 2775 | "email": "whatthejeff@gmail.com" 2776 | }, 2777 | { 2778 | "name": "Volker Dusch", 2779 | "email": "github@wallbash.com" 2780 | }, 2781 | { 2782 | "name": "Adam Harvey", 2783 | "email": "aharvey@php.net" 2784 | }, 2785 | { 2786 | "name": "Bernhard Schussek", 2787 | "email": "bschussek@gmail.com" 2788 | } 2789 | ], 2790 | "description": "Provides the functionality to export PHP variables for visualization", 2791 | "homepage": "https://www.github.com/sebastianbergmann/exporter", 2792 | "keywords": [ 2793 | "export", 2794 | "exporter" 2795 | ], 2796 | "support": { 2797 | "issues": "https://github.com/sebastianbergmann/exporter/issues", 2798 | "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" 2799 | }, 2800 | "funding": [ 2801 | { 2802 | "url": "https://github.com/sebastianbergmann", 2803 | "type": "github" 2804 | } 2805 | ], 2806 | "time": "2022-09-14T06:03:37+00:00" 2807 | }, 2808 | { 2809 | "name": "sebastian/global-state", 2810 | "version": "5.0.5", 2811 | "source": { 2812 | "type": "git", 2813 | "url": "https://github.com/sebastianbergmann/global-state.git", 2814 | "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" 2815 | }, 2816 | "dist": { 2817 | "type": "zip", 2818 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", 2819 | "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", 2820 | "shasum": "" 2821 | }, 2822 | "require": { 2823 | "php": ">=7.3", 2824 | "sebastian/object-reflector": "^2.0", 2825 | "sebastian/recursion-context": "^4.0" 2826 | }, 2827 | "require-dev": { 2828 | "ext-dom": "*", 2829 | "phpunit/phpunit": "^9.3" 2830 | }, 2831 | "suggest": { 2832 | "ext-uopz": "*" 2833 | }, 2834 | "type": "library", 2835 | "extra": { 2836 | "branch-alias": { 2837 | "dev-master": "5.0-dev" 2838 | } 2839 | }, 2840 | "autoload": { 2841 | "classmap": [ 2842 | "src/" 2843 | ] 2844 | }, 2845 | "notification-url": "https://packagist.org/downloads/", 2846 | "license": [ 2847 | "BSD-3-Clause" 2848 | ], 2849 | "authors": [ 2850 | { 2851 | "name": "Sebastian Bergmann", 2852 | "email": "sebastian@phpunit.de" 2853 | } 2854 | ], 2855 | "description": "Snapshotting of global state", 2856 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 2857 | "keywords": [ 2858 | "global state" 2859 | ], 2860 | "support": { 2861 | "issues": "https://github.com/sebastianbergmann/global-state/issues", 2862 | "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" 2863 | }, 2864 | "funding": [ 2865 | { 2866 | "url": "https://github.com/sebastianbergmann", 2867 | "type": "github" 2868 | } 2869 | ], 2870 | "time": "2022-02-14T08:28:10+00:00" 2871 | }, 2872 | { 2873 | "name": "sebastian/lines-of-code", 2874 | "version": "1.0.3", 2875 | "source": { 2876 | "type": "git", 2877 | "url": "https://github.com/sebastianbergmann/lines-of-code.git", 2878 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" 2879 | }, 2880 | "dist": { 2881 | "type": "zip", 2882 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", 2883 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", 2884 | "shasum": "" 2885 | }, 2886 | "require": { 2887 | "nikic/php-parser": "^4.6", 2888 | "php": ">=7.3" 2889 | }, 2890 | "require-dev": { 2891 | "phpunit/phpunit": "^9.3" 2892 | }, 2893 | "type": "library", 2894 | "extra": { 2895 | "branch-alias": { 2896 | "dev-master": "1.0-dev" 2897 | } 2898 | }, 2899 | "autoload": { 2900 | "classmap": [ 2901 | "src/" 2902 | ] 2903 | }, 2904 | "notification-url": "https://packagist.org/downloads/", 2905 | "license": [ 2906 | "BSD-3-Clause" 2907 | ], 2908 | "authors": [ 2909 | { 2910 | "name": "Sebastian Bergmann", 2911 | "email": "sebastian@phpunit.de", 2912 | "role": "lead" 2913 | } 2914 | ], 2915 | "description": "Library for counting the lines of code in PHP source code", 2916 | "homepage": "https://github.com/sebastianbergmann/lines-of-code", 2917 | "support": { 2918 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", 2919 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" 2920 | }, 2921 | "funding": [ 2922 | { 2923 | "url": "https://github.com/sebastianbergmann", 2924 | "type": "github" 2925 | } 2926 | ], 2927 | "time": "2020-11-28T06:42:11+00:00" 2928 | }, 2929 | { 2930 | "name": "sebastian/object-enumerator", 2931 | "version": "4.0.4", 2932 | "source": { 2933 | "type": "git", 2934 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 2935 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" 2936 | }, 2937 | "dist": { 2938 | "type": "zip", 2939 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", 2940 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", 2941 | "shasum": "" 2942 | }, 2943 | "require": { 2944 | "php": ">=7.3", 2945 | "sebastian/object-reflector": "^2.0", 2946 | "sebastian/recursion-context": "^4.0" 2947 | }, 2948 | "require-dev": { 2949 | "phpunit/phpunit": "^9.3" 2950 | }, 2951 | "type": "library", 2952 | "extra": { 2953 | "branch-alias": { 2954 | "dev-master": "4.0-dev" 2955 | } 2956 | }, 2957 | "autoload": { 2958 | "classmap": [ 2959 | "src/" 2960 | ] 2961 | }, 2962 | "notification-url": "https://packagist.org/downloads/", 2963 | "license": [ 2964 | "BSD-3-Clause" 2965 | ], 2966 | "authors": [ 2967 | { 2968 | "name": "Sebastian Bergmann", 2969 | "email": "sebastian@phpunit.de" 2970 | } 2971 | ], 2972 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 2973 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 2974 | "support": { 2975 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", 2976 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" 2977 | }, 2978 | "funding": [ 2979 | { 2980 | "url": "https://github.com/sebastianbergmann", 2981 | "type": "github" 2982 | } 2983 | ], 2984 | "time": "2020-10-26T13:12:34+00:00" 2985 | }, 2986 | { 2987 | "name": "sebastian/object-reflector", 2988 | "version": "2.0.4", 2989 | "source": { 2990 | "type": "git", 2991 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 2992 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" 2993 | }, 2994 | "dist": { 2995 | "type": "zip", 2996 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", 2997 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", 2998 | "shasum": "" 2999 | }, 3000 | "require": { 3001 | "php": ">=7.3" 3002 | }, 3003 | "require-dev": { 3004 | "phpunit/phpunit": "^9.3" 3005 | }, 3006 | "type": "library", 3007 | "extra": { 3008 | "branch-alias": { 3009 | "dev-master": "2.0-dev" 3010 | } 3011 | }, 3012 | "autoload": { 3013 | "classmap": [ 3014 | "src/" 3015 | ] 3016 | }, 3017 | "notification-url": "https://packagist.org/downloads/", 3018 | "license": [ 3019 | "BSD-3-Clause" 3020 | ], 3021 | "authors": [ 3022 | { 3023 | "name": "Sebastian Bergmann", 3024 | "email": "sebastian@phpunit.de" 3025 | } 3026 | ], 3027 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 3028 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 3029 | "support": { 3030 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues", 3031 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" 3032 | }, 3033 | "funding": [ 3034 | { 3035 | "url": "https://github.com/sebastianbergmann", 3036 | "type": "github" 3037 | } 3038 | ], 3039 | "time": "2020-10-26T13:14:26+00:00" 3040 | }, 3041 | { 3042 | "name": "sebastian/recursion-context", 3043 | "version": "4.0.5", 3044 | "source": { 3045 | "type": "git", 3046 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 3047 | "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" 3048 | }, 3049 | "dist": { 3050 | "type": "zip", 3051 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", 3052 | "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", 3053 | "shasum": "" 3054 | }, 3055 | "require": { 3056 | "php": ">=7.3" 3057 | }, 3058 | "require-dev": { 3059 | "phpunit/phpunit": "^9.3" 3060 | }, 3061 | "type": "library", 3062 | "extra": { 3063 | "branch-alias": { 3064 | "dev-master": "4.0-dev" 3065 | } 3066 | }, 3067 | "autoload": { 3068 | "classmap": [ 3069 | "src/" 3070 | ] 3071 | }, 3072 | "notification-url": "https://packagist.org/downloads/", 3073 | "license": [ 3074 | "BSD-3-Clause" 3075 | ], 3076 | "authors": [ 3077 | { 3078 | "name": "Sebastian Bergmann", 3079 | "email": "sebastian@phpunit.de" 3080 | }, 3081 | { 3082 | "name": "Jeff Welch", 3083 | "email": "whatthejeff@gmail.com" 3084 | }, 3085 | { 3086 | "name": "Adam Harvey", 3087 | "email": "aharvey@php.net" 3088 | } 3089 | ], 3090 | "description": "Provides functionality to recursively process PHP variables", 3091 | "homepage": "https://github.com/sebastianbergmann/recursion-context", 3092 | "support": { 3093 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues", 3094 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" 3095 | }, 3096 | "funding": [ 3097 | { 3098 | "url": "https://github.com/sebastianbergmann", 3099 | "type": "github" 3100 | } 3101 | ], 3102 | "time": "2023-02-03T06:07:39+00:00" 3103 | }, 3104 | { 3105 | "name": "sebastian/resource-operations", 3106 | "version": "3.0.3", 3107 | "source": { 3108 | "type": "git", 3109 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 3110 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" 3111 | }, 3112 | "dist": { 3113 | "type": "zip", 3114 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", 3115 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", 3116 | "shasum": "" 3117 | }, 3118 | "require": { 3119 | "php": ">=7.3" 3120 | }, 3121 | "require-dev": { 3122 | "phpunit/phpunit": "^9.0" 3123 | }, 3124 | "type": "library", 3125 | "extra": { 3126 | "branch-alias": { 3127 | "dev-master": "3.0-dev" 3128 | } 3129 | }, 3130 | "autoload": { 3131 | "classmap": [ 3132 | "src/" 3133 | ] 3134 | }, 3135 | "notification-url": "https://packagist.org/downloads/", 3136 | "license": [ 3137 | "BSD-3-Clause" 3138 | ], 3139 | "authors": [ 3140 | { 3141 | "name": "Sebastian Bergmann", 3142 | "email": "sebastian@phpunit.de" 3143 | } 3144 | ], 3145 | "description": "Provides a list of PHP built-in functions that operate on resources", 3146 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 3147 | "support": { 3148 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues", 3149 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" 3150 | }, 3151 | "funding": [ 3152 | { 3153 | "url": "https://github.com/sebastianbergmann", 3154 | "type": "github" 3155 | } 3156 | ], 3157 | "time": "2020-09-28T06:45:17+00:00" 3158 | }, 3159 | { 3160 | "name": "sebastian/type", 3161 | "version": "3.2.1", 3162 | "source": { 3163 | "type": "git", 3164 | "url": "https://github.com/sebastianbergmann/type.git", 3165 | "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" 3166 | }, 3167 | "dist": { 3168 | "type": "zip", 3169 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", 3170 | "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", 3171 | "shasum": "" 3172 | }, 3173 | "require": { 3174 | "php": ">=7.3" 3175 | }, 3176 | "require-dev": { 3177 | "phpunit/phpunit": "^9.5" 3178 | }, 3179 | "type": "library", 3180 | "extra": { 3181 | "branch-alias": { 3182 | "dev-master": "3.2-dev" 3183 | } 3184 | }, 3185 | "autoload": { 3186 | "classmap": [ 3187 | "src/" 3188 | ] 3189 | }, 3190 | "notification-url": "https://packagist.org/downloads/", 3191 | "license": [ 3192 | "BSD-3-Clause" 3193 | ], 3194 | "authors": [ 3195 | { 3196 | "name": "Sebastian Bergmann", 3197 | "email": "sebastian@phpunit.de", 3198 | "role": "lead" 3199 | } 3200 | ], 3201 | "description": "Collection of value objects that represent the types of the PHP type system", 3202 | "homepage": "https://github.com/sebastianbergmann/type", 3203 | "support": { 3204 | "issues": "https://github.com/sebastianbergmann/type/issues", 3205 | "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" 3206 | }, 3207 | "funding": [ 3208 | { 3209 | "url": "https://github.com/sebastianbergmann", 3210 | "type": "github" 3211 | } 3212 | ], 3213 | "time": "2023-02-03T06:13:03+00:00" 3214 | }, 3215 | { 3216 | "name": "sebastian/version", 3217 | "version": "3.0.2", 3218 | "source": { 3219 | "type": "git", 3220 | "url": "https://github.com/sebastianbergmann/version.git", 3221 | "reference": "c6c1022351a901512170118436c764e473f6de8c" 3222 | }, 3223 | "dist": { 3224 | "type": "zip", 3225 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", 3226 | "reference": "c6c1022351a901512170118436c764e473f6de8c", 3227 | "shasum": "" 3228 | }, 3229 | "require": { 3230 | "php": ">=7.3" 3231 | }, 3232 | "type": "library", 3233 | "extra": { 3234 | "branch-alias": { 3235 | "dev-master": "3.0-dev" 3236 | } 3237 | }, 3238 | "autoload": { 3239 | "classmap": [ 3240 | "src/" 3241 | ] 3242 | }, 3243 | "notification-url": "https://packagist.org/downloads/", 3244 | "license": [ 3245 | "BSD-3-Clause" 3246 | ], 3247 | "authors": [ 3248 | { 3249 | "name": "Sebastian Bergmann", 3250 | "email": "sebastian@phpunit.de", 3251 | "role": "lead" 3252 | } 3253 | ], 3254 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 3255 | "homepage": "https://github.com/sebastianbergmann/version", 3256 | "support": { 3257 | "issues": "https://github.com/sebastianbergmann/version/issues", 3258 | "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" 3259 | }, 3260 | "funding": [ 3261 | { 3262 | "url": "https://github.com/sebastianbergmann", 3263 | "type": "github" 3264 | } 3265 | ], 3266 | "time": "2020-09-28T06:39:44+00:00" 3267 | }, 3268 | { 3269 | "name": "theseer/tokenizer", 3270 | "version": "1.2.1", 3271 | "source": { 3272 | "type": "git", 3273 | "url": "https://github.com/theseer/tokenizer.git", 3274 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" 3275 | }, 3276 | "dist": { 3277 | "type": "zip", 3278 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", 3279 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", 3280 | "shasum": "" 3281 | }, 3282 | "require": { 3283 | "ext-dom": "*", 3284 | "ext-tokenizer": "*", 3285 | "ext-xmlwriter": "*", 3286 | "php": "^7.2 || ^8.0" 3287 | }, 3288 | "type": "library", 3289 | "autoload": { 3290 | "classmap": [ 3291 | "src/" 3292 | ] 3293 | }, 3294 | "notification-url": "https://packagist.org/downloads/", 3295 | "license": [ 3296 | "BSD-3-Clause" 3297 | ], 3298 | "authors": [ 3299 | { 3300 | "name": "Arne Blankerts", 3301 | "email": "arne@blankerts.de", 3302 | "role": "Developer" 3303 | } 3304 | ], 3305 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 3306 | "support": { 3307 | "issues": "https://github.com/theseer/tokenizer/issues", 3308 | "source": "https://github.com/theseer/tokenizer/tree/1.2.1" 3309 | }, 3310 | "funding": [ 3311 | { 3312 | "url": "https://github.com/theseer", 3313 | "type": "github" 3314 | } 3315 | ], 3316 | "time": "2021-07-28T10:34:58+00:00" 3317 | }, 3318 | { 3319 | "name": "v.chetkov/php-clean-architecture", 3320 | "version": "0.1.2", 3321 | "source": { 3322 | "type": "git", 3323 | "url": "https://github.com/Chetkov/php-clean-architecture.git", 3324 | "reference": "de2f1d037ed0cbecb2830df5c5ab69f3bfde8a1b" 3325 | }, 3326 | "dist": { 3327 | "type": "zip", 3328 | "url": "https://api.github.com/repos/Chetkov/php-clean-architecture/zipball/de2f1d037ed0cbecb2830df5c5ab69f3bfde8a1b", 3329 | "reference": "de2f1d037ed0cbecb2830df5c5ab69f3bfde8a1b", 3330 | "shasum": "" 3331 | }, 3332 | "require": { 3333 | "ext-json": "*", 3334 | "ext-mbstring": "*", 3335 | "psr/log": "*", 3336 | "twig/twig": "*" 3337 | }, 3338 | "require-dev": { 3339 | "phpstan/phpstan": "^0.12.90", 3340 | "squizlabs/php_codesniffer": "^3.6" 3341 | }, 3342 | "bin": [ 3343 | "bin/phpca-build-reports", 3344 | "bin/phpca-check", 3345 | "bin/phpca-allow-current-state" 3346 | ], 3347 | "type": "library", 3348 | "autoload": { 3349 | "psr-4": { 3350 | "Chetkov\\PHPCleanArchitecture\\": "src/" 3351 | } 3352 | }, 3353 | "notification-url": "https://packagist.org/downloads/", 3354 | "license": [ 3355 | "MIT" 3356 | ], 3357 | "authors": [ 3358 | { 3359 | "name": "Валерий Четков", 3360 | "email": "chetkov.valeriy@gmail.com" 3361 | } 3362 | ], 3363 | "description": "PHP Clean Architecture", 3364 | "support": { 3365 | "issues": "https://github.com/Chetkov/php-clean-architecture/issues", 3366 | "source": "https://github.com/Chetkov/php-clean-architecture/tree/0.1.2" 3367 | }, 3368 | "time": "2022-09-03T17:00:00+00:00" 3369 | } 3370 | ], 3371 | "aliases": [], 3372 | "minimum-stability": "stable", 3373 | "stability-flags": [], 3374 | "prefer-stable": false, 3375 | "prefer-lowest": false, 3376 | "platform": [], 3377 | "platform-dev": [], 3378 | "plugin-api-version": "2.3.0" 3379 | } 3380 | -------------------------------------------------------------------------------- /phpca-config-all.php: -------------------------------------------------------------------------------- 1 | __DIR__ . '/phpca-reports', 55 | 56 | // Учет vendor пакетов (каждый подключенный пакет, за исключением перечисленных в excluded, будет представлен компонентом) 57 | 'vendor_based_components' => [ 58 | 'enabled' => false, 59 | 'vendor_path' => __DIR__ . '/vendor', 60 | ], 61 | 62 | // Общие для всех компонентов ограничения 63 | 'restrictions' => [ 64 | // Включение/отключение обнаружения нарушений принципа ацикличности зависимостей. 65 | 'check_acyclic_dependencies_principle' => true, 66 | 67 | // Включение/отключение обнаружения нарушений принципа устойчивых зависимостей. 68 | 'check_stable_dependencies_principle' => true, 69 | 70 | ], 71 | 72 | // Описание компонентов и их ограничений 73 | 'components' => [ 74 | 75 | // model 76 | [ 77 | 'name' => 'model', 78 | 'roots' => [ 79 | [ 80 | 'path' => __DIR__ . '/src/ExampleApp/Core/Model', 81 | 'namespace' => '\ExampleApp\Core\Model', 82 | ], 83 | ], 84 | 85 | ], 86 | 87 | // input ports 88 | [ 89 | 'name' => 'input ports', 90 | 'roots' => [ 91 | [ 92 | 'path' => __DIR__ . '/src/ExampleApp/Core/Port/Input', 93 | 'namespace' => '\ExampleApp\Core\Port\Input', 94 | ], 95 | ], 96 | 97 | ], 98 | 99 | // output ports (sec. adapt.) 100 | [ 101 | 'name' => 'output ports (sec. adapt.)', 102 | 'roots' => [ 103 | [ 104 | 'path' => __DIR__ . '/src/ExampleApp/Core/Port/Output', 105 | 'namespace' => '\ExampleApp\Core\Port\Output', 106 | ], 107 | ], 108 | 109 | ], 110 | 111 | // output ports (presenters) 112 | [ 113 | 'name' => 'output ports (presenters)', 114 | 'roots' => [ 115 | [ 116 | 'path' => __DIR__ . '/src/ExampleApp/Core/Port/Presenter', 117 | 'namespace' => '\ExampleApp\Core\Port\Presenter', 118 | ], 119 | ], 120 | 121 | ], 122 | 123 | // use cases 124 | [ 125 | 'name' => 'use cases', 126 | 'roots' => [ 127 | [ 128 | 'path' => __DIR__ . '/src/ExampleApp/Core/UseCase', 129 | 'namespace' => '\ExampleApp\Core\UseCase', 130 | ], 131 | ], 132 | 133 | ], 134 | 135 | // controllers 136 | [ 137 | 'name' => 'controllers', 138 | 'roots' => [ 139 | [ 140 | 'path' => __DIR__ . '/src/ExampleApp/Infrastructure/Adapter/Web/Controller', 141 | 'namespace' => '\ExampleApp\Infrastructure\Adapter\Web\Controller', 142 | ], 143 | ], 144 | 145 | ], 146 | 147 | // presenters 148 | [ 149 | 'name' => 'presenters', 150 | 'roots' => [ 151 | [ 152 | 'path' => __DIR__ . '/src/ExampleApp/Infrastructure/Adapter/Web/Presenter', 153 | 'namespace' => '\ExampleApp\Infrastructure\Adapter\Web\Presenter', 154 | ], 155 | ], 156 | 157 | ], 158 | 159 | // secondary adapters 160 | [ 161 | 'name' => 'secondary adapters', 162 | 'roots' => [ 163 | [ 164 | 'path' => __DIR__ . '/src/ExampleApp/Infrastructure/Adapter', 165 | 'namespace' => '\ExampleApp\Infrastructure\Adapter', 166 | ], 167 | ], 168 | 'excluded' => [ 169 | __DIR__ . '/src/ExampleApp/Infrastructure/Adapter/Web', 170 | ], 171 | ], 172 | 173 | // application 174 | [ 175 | 'is_analyze_enabled' => false, 176 | 'name' => 'application', 177 | 'roots' => [ 178 | [ 179 | 'path' => __DIR__ . '/src/ExampleApp/Infrastructure/Application', 180 | 'namespace' => '\ExampleApp\Infrastructure\Application', 181 | ], 182 | ], 183 | ], 184 | 185 | ], 186 | 187 | 'factories' => [ 188 | //Фабрика, собирающая DependenciesFinder 189 | 'dependencies_finder' => static function (): DependenciesFinderInterface { 190 | return new CompositeDependenciesFinder(...[ 191 | new ReflectionDependenciesFinder(), 192 | new CodeParsingDependenciesFinder(...[ 193 | new ClassesCreatedThroughNewParsingStrategy(), 194 | new ClassesCalledStaticallyParsingStrategy(), 195 | new ClassesFromInstanceofConstructionParsingStrategy(), 196 | new PropertyAnnotationsParsingStrategy(), 197 | new MethodAnnotationsParsingStrategy(), 198 | new ParamAnnotationsParsingStrategy(), 199 | new ReturnAnnotationsParsingStrategy(), 200 | new ThrowsAnnotationsParsingStrategy(), 201 | new VarAnnotationsParsingStrategy(), 202 | ]), 203 | ]); 204 | }, 205 | //Фабрика, собирающая сервис рендеринга отчетов 206 | 'report_rendering_service' => static function (EventManagerInterface $eventManager): ReportRenderingServiceInterface { 207 | $templatesLoader = new FilesystemLoader(ReportRenderingService::templatesPath()); 208 | $twigRenderer = new Environment($templatesLoader); 209 | $twigAdapter = new TwigToTemplateRendererInterfaceAdapter($twigRenderer); 210 | return new ReportRenderingService($eventManager, $twigAdapter); 211 | }, 212 | //Фабрика, собирающая и настраивающая EventManager 213 | 'event_manager' => static function (): EventManagerInterface { 214 | return new EventManager([ 215 | new ReportBuildingEventListener(), 216 | new AnalysisEventListener(), 217 | new ComponentAnalysisEventListener(), 218 | new FileAnalyzedEventListener(), 219 | new ReportBuildingEventListener(), 220 | new ReportRenderingEventListener(), 221 | new ComponentReportRenderingEventListener(), 222 | new UnitOfCodeReportRenderedEventListener(), 223 | ]); 224 | } 225 | ], 226 | ]; -------------------------------------------------------------------------------- /phpca-config.php: -------------------------------------------------------------------------------- 1 | __DIR__ . '/phpca-reports', 55 | 56 | // Учет vendor пакетов (каждый подключенный пакет, за исключением перечисленных в excluded, будет представлен компонентом) 57 | 'vendor_based_components' => [ 58 | 'enabled' => false, 59 | 'vendor_path' => __DIR__ . '/vendor', 60 | ], 61 | 62 | // Общие для всех компонентов ограничения 63 | 'restrictions' => [ 64 | // Включение/отключение обнаружения нарушений принципа ацикличности зависимостей. 65 | 'check_acyclic_dependencies_principle' => true, 66 | 67 | // Включение/отключение обнаружения нарушений принципа устойчивых зависимостей. 68 | 'check_stable_dependencies_principle' => true, 69 | 70 | ], 71 | 72 | // Описание компонентов и их ограничений 73 | 'components' => [ 74 | 75 | // core 76 | [ 77 | 'name' => 'core', 78 | 'roots' => [ 79 | [ 80 | 'path' => __DIR__ . '/src/ExampleApp/Core', 81 | 'namespace' => '\ExampleApp\Core', 82 | ], 83 | ], 84 | 85 | // core must not depend on infrastructure 86 | 'restrictions' => [ 87 | 'forbidden_dependencies' => ['infrastructure'], 88 | ], 89 | 90 | ], 91 | 92 | // infrastructure 93 | [ 94 | 'name' => 'infrastructure', 95 | 'roots' => [ 96 | [ 97 | 'path' => __DIR__ . '/src/ExampleApp/Infrastructure', 98 | 'namespace' => '\ExampleApp\Infrastructure', 99 | ], 100 | ], 101 | 102 | ], 103 | 104 | ], 105 | 106 | 'factories' => [ 107 | //Фабрика, собирающая DependenciesFinder 108 | 'dependencies_finder' => static function (): DependenciesFinderInterface { 109 | return new CompositeDependenciesFinder(...[ 110 | new ReflectionDependenciesFinder(), 111 | new CodeParsingDependenciesFinder(...[ 112 | new ClassesCreatedThroughNewParsingStrategy(), 113 | new ClassesCalledStaticallyParsingStrategy(), 114 | new ClassesFromInstanceofConstructionParsingStrategy(), 115 | new PropertyAnnotationsParsingStrategy(), 116 | new MethodAnnotationsParsingStrategy(), 117 | new ParamAnnotationsParsingStrategy(), 118 | new ReturnAnnotationsParsingStrategy(), 119 | new ThrowsAnnotationsParsingStrategy(), 120 | new VarAnnotationsParsingStrategy(), 121 | ]), 122 | ]); 123 | }, 124 | //Фабрика, собирающая сервис рендеринга отчетов 125 | 'report_rendering_service' => static function (EventManagerInterface $eventManager): ReportRenderingServiceInterface { 126 | $templatesLoader = new FilesystemLoader(ReportRenderingService::templatesPath()); 127 | $twigRenderer = new Environment($templatesLoader); 128 | $twigAdapter = new TwigToTemplateRendererInterfaceAdapter($twigRenderer); 129 | return new ReportRenderingService($eventManager, $twigAdapter); 130 | }, 131 | //Фабрика, собирающая и настраивающая EventManager 132 | 'event_manager' => static function (): EventManagerInterface { 133 | return new EventManager([ 134 | new ReportBuildingEventListener(), 135 | new AnalysisEventListener(), 136 | new ComponentAnalysisEventListener(), 137 | new FileAnalyzedEventListener(), 138 | new ReportBuildingEventListener(), 139 | new ReportRenderingEventListener(), 140 | new ComponentReportRenderingEventListener(), 141 | new UnitOfCodeReportRenderedEventListener(), 142 | ]); 143 | } 144 | ], 145 | ]; -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | setupPersistence(__DIR__ . '/../db'); 29 | 30 | // set up templates processing engine 31 | $templatesProcessor = $app->setupTemplatesProcessor(__DIR__ . '/../templates'); 32 | 33 | // set up response emitter 34 | $responseEmitter = $app->setupResponseEmitter(); 35 | 36 | // set up DI container 37 | $container = $app->setupContainer($templatesProcessor, $responseEmitter, $store); 38 | 39 | // set up route dispatcher 40 | $routes = $app->setupRouting(); 41 | 42 | // set up request handling middleware 43 | $requestHandler = $app->setupMiddleware($routes, $container); 44 | 45 | // run the application 46 | $app->run($requestHandler, $container); 47 | -------------------------------------------------------------------------------- /src/ExampleApp/Core/Model/Author.php: -------------------------------------------------------------------------------- 1 | name = $name; 20 | } 21 | 22 | /** 23 | * @return string 24 | */ 25 | public function getName(): string 26 | { 27 | return $this->name; 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/ExampleApp/Core/Model/GenericExampleAppError.php: -------------------------------------------------------------------------------- 1 | greetingId = $greetingId; 31 | if (empty($text)) { 32 | throw new InvalidDomainObjectError("Greeting must not have an empty text."); 33 | } 34 | $this->text = $text; 35 | $this->author = $author; 36 | } 37 | 38 | /** 39 | * @return GreetingId 40 | */ 41 | public function getGreetingId(): GreetingId 42 | { 43 | return $this->greetingId; 44 | } 45 | 46 | /** 47 | * @return string 48 | */ 49 | public function getText(): string 50 | { 51 | return $this->text; 52 | } 53 | 54 | /** 55 | * @return Author 56 | */ 57 | public function getAuthor(): Author 58 | { 59 | return $this->author; 60 | } 61 | 62 | public function fullGreetingMessage(): string 63 | { 64 | return "#{$this->greetingId->getId()}: $this->text (by {$this->author->getName()})"; 65 | } 66 | 67 | /** 68 | * @throws InvalidDomainObjectError 69 | */ 70 | public function withAuthorName(string $author): Greeting 71 | { 72 | return $this->with(null, 73 | null, 74 | new Author($author)); 75 | } 76 | 77 | /** 78 | * @throws InvalidDomainObjectError 79 | */ 80 | private function with(GreetingId $greetingId = null, 81 | string $text = null, 82 | Author $author = null): Greeting 83 | { 84 | return new Greeting( 85 | $greetingId ?: $this->greetingId, 86 | $text ?: $this->text, 87 | $author ?: $this->author 88 | ); 89 | } 90 | } -------------------------------------------------------------------------------- /src/ExampleApp/Core/Model/GreetingId.php: -------------------------------------------------------------------------------- 1 | id = $id; 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getId(): string 38 | { 39 | return $this->id; 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /src/ExampleApp/Core/Model/InvalidDomainObjectError.php: -------------------------------------------------------------------------------- 1 | presenter = $presenter; 29 | $this->configOps = $configOps; 30 | $this->securityOps = $securityOps; 31 | } 32 | 33 | public function initiateLogin(): void 34 | { 35 | 36 | $this->presenter->showLoginForm(); 37 | } 38 | 39 | 40 | public function login(string $submittedUsername, string $submittedPassword): void 41 | { 42 | try { 43 | $this->securityOps->registerLogin([ 44 | 'username' => $this->configOps->username(), 45 | 'password' => $this->configOps->password() 46 | ], 47 | [ 48 | 'username' => $submittedUsername, 49 | 'password' => $submittedPassword 50 | ]); 51 | } catch (InvalidLoginCredentialsError $e) { 52 | $this->presenter->presentError($e); 53 | return; 54 | } 55 | 56 | $this->presenter->acceptLogin(); 57 | } 58 | } -------------------------------------------------------------------------------- /src/ExampleApp/Core/UseCase/SayHello/SayHelloUseCase.php: -------------------------------------------------------------------------------- 1 | presenter = $presenter; 33 | $this->gatewayOps = $gatewayOps; 34 | } 35 | 36 | public function greetUser(): void 37 | { 38 | /* 39 | * Each use case will perform some (small) amount of business logic 40 | * necessary to implement the scenario. This will usually involve 41 | * one or several calls to any output ports (retrieving or persisting 42 | * entities from or to the gateway, for example). Any security checks, 43 | * such as permission of the current user to perform any action with 44 | * any of the models, will be done at this point in the use case. 45 | * Use case will usually call the Presenter either requesting a successful 46 | * presentation of the results of the business process or requesting 47 | * to present any errors. 48 | */ 49 | 50 | $id = rand(1, 5); 51 | try { 52 | $greeting = $this->gatewayOps->obtainGreetingById(GreetingId::of($id)); 53 | } catch (InvalidDomainObjectError|GreetingPersistenceError $e) { 54 | $this->presenter->presentError($e); 55 | return; 56 | } 57 | 58 | $this->presenter->presentGreetingToUser($greeting); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/ExampleApp/Core/UseCase/UpdateAuthor/UpdateAuthorUseCase.php: -------------------------------------------------------------------------------- 1 | presenter = $presenter; 33 | $this->gatewayOps = $gatewayOps; 34 | $this->securityOps = $securityOps; 35 | } 36 | 37 | public function editAuthorOfGreeting() 38 | { 39 | $this->presenter->presentEditAuthorOfGreetingView(); 40 | } 41 | 42 | /* 43 | * Validating types of inputs to the use case follow the same 44 | * logic as any other operation in the use case: when instantiating 45 | * value objects or calling an output ports, for example. See 46 | * "TypeError" exception in the "try-catch" below. 47 | */ 48 | 49 | public function updateAuthorOfGreeting(string|int $greetingId, string $updatedAuthorName): void 50 | { 51 | 52 | try { 53 | 54 | /* 55 | * Security checks are done in the use cases. Here 56 | * we assert that the current user is authenticated 57 | * before actually updating a greeting. 58 | */ 59 | $this->securityOps->assertUserIsLoggedIn(); 60 | 61 | // construct GreetingID value object 62 | $greetingId = GreetingId::of($greetingId); 63 | // find the greeting 64 | $greeting = $this->gatewayOps->obtainGreetingById($greetingId); 65 | // make new (updated) greeting 66 | $updatedGreeting = $greeting->withAuthorName($updatedAuthorName); 67 | // persist updated greeting 68 | $this->gatewayOps->updateGreeting($updatedGreeting); 69 | } catch (UserNotAuthenticatedError|TypeError|InvalidDomainObjectError|GreetingPersistenceError $e) { 70 | $this->presenter->presentError($e); 71 | return; 72 | } 73 | 74 | $this->presenter->presentAuthorUpdatedSuccessfully($greetingId); 75 | } 76 | } -------------------------------------------------------------------------------- /src/ExampleApp/Core/UseCase/Welcome/WelcomeUseCase.php: -------------------------------------------------------------------------------- 1 | presenter = $presenter; 23 | $this->securityOps = $securityOps; 24 | } 25 | 26 | public function welcome(): void 27 | { 28 | // see if the user is logged in and get her username 29 | 30 | $username = 'undefined'; 31 | try { 32 | $isUserLoggedIn = $this->securityOps->isUserLoggedIn(); 33 | if ($isUserLoggedIn) { 34 | $username = $this->securityOps->username(); 35 | } 36 | } catch (UserNotAuthenticatedError $e) { 37 | $this->presenter->presentError($e); 38 | return; 39 | } 40 | 41 | $this->presenter->presentWelcomeView($isUserLoggedIn, $username); 42 | } 43 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Config/ConfigAdapter.php: -------------------------------------------------------------------------------- 1 | props = [ 17 | 'username' => 'user1', 18 | 'password' => 'test' 19 | ]; 20 | } 21 | 22 | public function username(): string 23 | { 24 | return $this->props['username']; 25 | } 26 | 27 | public function password(): string 28 | { 29 | return $this->props['password']; 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Db/FilePersistenceGateway.php: -------------------------------------------------------------------------------- 1 | store = $store; 39 | $this->mapper = $mapper; 40 | } 41 | 42 | /** 43 | * @throws GreetingPersistenceError 44 | */ 45 | public function obtainGreetingById(GreetingId $greetingId): Greeting 46 | { 47 | $id = $greetingId->getId(); 48 | try { 49 | $dto = $this->store->findById($id); 50 | } catch (InvalidArgumentException $e) { 51 | throw new GreetingPersistenceError("Invalid ID for DB operation. {$e->getMessage()}"); 52 | } 53 | if ($dto == null) { 54 | throw new GreetingPersistenceError("Could not find Greeting with ID: $id in the database"); 55 | } 56 | try { 57 | return $this->mapper->convertFromArrayToGreeting($dto); 58 | } catch (InvalidDomainObjectError $e) { 59 | throw new GreetingPersistenceError("Cannot map greeting with ID $id from DB entity. {$e->getMessage()}"); 60 | } 61 | } 62 | 63 | /** 64 | * @throws GreetingPersistenceError 65 | */ 66 | public function updateGreeting(Greeting $updatedGreeting): void 67 | { 68 | try { 69 | $dbGreeting = $this->mapper->convertFromGreetingToArray($updatedGreeting); 70 | $this->store->updateById($updatedGreeting->getGreetingId()->getId(), $dbGreeting); 71 | } catch (IOException|InvalidArgumentException|JsonException $e) { 72 | throw new GreetingPersistenceError("Could not update greeting with ID: " . 73 | $updatedGreeting->getGreetingId()->getId() . 74 | " {$e->getMessage()}"); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Db/PersistenceMapper.php: -------------------------------------------------------------------------------- 1 | $author->getName()]; 29 | } 30 | 31 | /** 32 | * @throws InvalidDomainObjectError 33 | */ 34 | function convertFromArrayToGreeting(array $dto): Greeting 35 | { 36 | return new Greeting(GreetingId::of($dto['_id']), 37 | $dto['text'], 38 | $this->convertFromArrayToAuthor($dto['author'])); 39 | } 40 | 41 | function convertFromGreetingToArray(Greeting $greeting): array 42 | { 43 | return [ 44 | 'text' => $greeting->getText(), 45 | 'author' => $this->convertFromAuthorToArray($greeting->getAuthor()) 46 | ]; 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Security/SessionBackedSecurityAdapter.php: -------------------------------------------------------------------------------- 1 | isUserLoggedIn()) { 54 | throw new UserNotAuthenticatedError("Cannot perform this action if not authenticated"); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Web/Controller/Login/LoginController.php: -------------------------------------------------------------------------------- 1 | useCase = $useCase; 19 | } 20 | 21 | public function __invoke(ServerRequestInterface $request): void 22 | { 23 | 24 | if ($request->getServerParams()['PATH_INFO'] === '/login') { 25 | $this->initiateLogin(); 26 | } elseif ($request->getServerParams()['PATH_INFO'] === '/process-login') { 27 | $this->processLogin($request); 28 | } 29 | 30 | } 31 | 32 | private function initiateLogin(): void 33 | { 34 | $this->useCase->initiateLogin(); 35 | } 36 | 37 | private function processLogin(ServerRequestInterface $request): void 38 | { 39 | $form = $request->getParsedBody(); 40 | $this->useCase->login($form['username'], $form['password']); 41 | } 42 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Web/Controller/SayHello/SayHelloController.php: -------------------------------------------------------------------------------- 1 | useCase = $useCase; 26 | } 27 | 28 | public function __invoke(): void 29 | { 30 | 31 | $this->useCase->greetUser(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Web/Controller/UpdateAuthor/UpdateAuthorController.php: -------------------------------------------------------------------------------- 1 | useCase = $useCase; 19 | } 20 | 21 | 22 | public function __invoke(ServerRequestInterface $request): void 23 | { 24 | 25 | if ($request->getServerParams()['PATH_INFO'] === '/edit-author') { 26 | $this->editAuthor(); 27 | } elseif ($request->getServerParams()['PATH_INFO'] === '/update-author') { 28 | $this->updateAuthor($request); 29 | } 30 | 31 | } 32 | 33 | private function editAuthor(): void 34 | { 35 | 36 | $this->useCase->editAuthorOfGreeting(); 37 | } 38 | 39 | private function updateAuthor(ServerRequestInterface $request): void 40 | { 41 | // parse input parameters 42 | $form = $request->getParsedBody(); 43 | 44 | // execute use case 45 | $this->useCase->updateAuthorOfGreeting($form['greetingId'], $form['authorName']); 46 | 47 | } 48 | 49 | 50 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Web/Controller/Welcome/WelcomeController.php: -------------------------------------------------------------------------------- 1 | useCase = $useCase; 18 | } 19 | 20 | public function __invoke(): void 21 | { 22 | $this->useCase->welcome(); 23 | } 24 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Web/Presenter/AbstractWebPresenter.php: -------------------------------------------------------------------------------- 1 | response = $response; 22 | $this->responseEmitter = $responseEmitter; 23 | $this->templatesProcessor = $templatesProcessor; 24 | } 25 | 26 | public function presentError(Throwable $error) 27 | { 28 | // log error 29 | error_log("Error: {$error->getMessage()}", 4); 30 | $this->presentTemplatedResponse('error.html', ['message' => $error->getMessage()], 500); 31 | } 32 | 33 | protected function presentTemplatedResponse(string $template, $args = [], int $status = 200, 34 | string $contentType = 'text/html'): void 35 | { 36 | $response = $this->response->withHeader('Content-Type', $contentType) 37 | ->withStatus($status); 38 | 39 | $body = $this->templatesProcessor->processTemplate($template, $args); 40 | 41 | $response->getBody()->write($body); 42 | $this->responseEmitter->emit($response); 43 | } 44 | 45 | protected function redirect(string $redirectUri): void 46 | { 47 | 48 | header('Location: ' . $redirectUri); 49 | 50 | } 51 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Web/Presenter/Login/LoginPresenter.php: -------------------------------------------------------------------------------- 1 | presentTemplatedResponse('login.html'); 14 | } 15 | 16 | public function acceptLogin(): void 17 | { 18 | $this->presentTemplatedResponse('login-success.html'); 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Web/Presenter/SayHello/SayHelloPresenter.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gushakov/clean-php/c153fae48c5a725b9ab47383658942c1fd1d658e/src/ExampleApp/Infrastructure/Adapter/Web/Presenter/SayHello/SayHelloPresenter.php -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Web/Presenter/UpdateAuthor/UpdateAuthorPresenter.php: -------------------------------------------------------------------------------- 1 | presentTemplatedResponse('edit-author.html'); 15 | } 16 | 17 | public function presentAuthorUpdatedSuccessfully(GreetingId $greetingId) 18 | { 19 | $this->presentTemplatedResponse('update-author-success.html', 20 | [ 21 | 'greetingId' => $greetingId->getId() 22 | ]); 23 | } 24 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Adapter/Web/Presenter/Welcome/WelcomePresenter.php: -------------------------------------------------------------------------------- 1 | presentTemplatedResponse('welcome.html', [ 15 | 'userLoggedIn' => $isUserLoggedIn, 16 | 'username' => $username 17 | ]); 18 | } 19 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Application/App.php: -------------------------------------------------------------------------------- 1 | useAutowiring(true); 83 | $containerBuilder->useAnnotations(false); 84 | $containerBuilder->addDefinitions([ 85 | 86 | // PSR-7 request and response 87 | ResponseInterface::class => create(Response::class), 88 | ServerRequestInterface::class => function () { 89 | return ServerRequestFactory::fromGlobals(); 90 | }, 91 | 92 | // template processor, response emitter, etc. 93 | TemplatesProcessor::class => $templatesProcessor, 94 | ResponseEmitter::class => $responseEmitter, 95 | 96 | // persistence store, mapper, etc. 97 | Store::class => $store, 98 | PersistenceMapper::class => create(PersistenceMapper::class), 99 | PersistenceGatewayOperationsOutputPort::class => autowire(FilePersistenceGateway::class), 100 | 101 | // security adapter 102 | SecurityOperationsOutputPort::class => create(SessionBackedSecurityAdapter::class), 103 | 104 | // configuration adapter 105 | ConfigOperationsOutputPort::class => create(ConfigAdapter::class), 106 | 107 | // presenters, input ports (par use case) 108 | WelcomePresenterOutputPort::class => autowire(WelcomePresenter::class), 109 | WelcomeInputPort::class => autowire(WelcomeUseCase::class), 110 | 111 | SayHelloPresenterOutputPort::class => autowire(SayHelloPresenter::class), 112 | SayHelloInputPort::class => autowire(SayHelloUseCase::class), 113 | 114 | UpdateAuthorPresenterOutputPort::class => autowire(UpdateAuthorPresenter::class), 115 | UpdateAuthorInputPort::class => autowire(UpdateAuthorUseCase::class), 116 | 117 | LoginPresenterOutputPort::class => autowire(LoginPresenter::class), 118 | LoginUserInputPort::class => autowire(LoginUserUseCase::class) 119 | 120 | ]); 121 | return $containerBuilder->build(); 122 | } 123 | 124 | public function setupRouting(): Dispatcher 125 | { 126 | return simpleDispatcher(function (RouteCollector $r) { 127 | $r->get('/', WelcomeController::class); 128 | $r->get('/hello', SayHelloController::class); 129 | $r->get('/edit-author', UpdateAuthorController::class); 130 | $r->post('/update-author', UpdateAuthorController::class); 131 | $r->get('/login', LoginController::class); 132 | $r->post('/process-login', LoginController::class); 133 | }); 134 | } 135 | 136 | public function setupMiddleware(Dispatcher $routes, ContainerInterface $container): RequestHandlerInterface 137 | { 138 | $middlewareQueue[] = new FastRoute($routes); 139 | $middlewareQueue[] = new RequestHandler($container); 140 | return new Relay($middlewareQueue); 141 | 142 | } 143 | 144 | public function setupPersistence(string $dbPath): Store 145 | { 146 | $store = new Store('greetings', $dbPath, 147 | ['timeout' => false]); 148 | 149 | // do not reinitialize the store 150 | if ($store->count() == 0) { 151 | $this->insertData($store); 152 | } 153 | 154 | return $store; 155 | } 156 | 157 | public function run(RequestHandlerInterface $requestHandler, ContainerInterface $container): void 158 | { 159 | 160 | $request = $container->get(ServerRequestInterface::class); 161 | $requestHandler->handle($request); 162 | } 163 | 164 | /** 165 | * @throws IOException 166 | * @throws JsonException 167 | * @throws InvalidArgumentException 168 | */ 169 | private function insertData(Store $store): void 170 | { 171 | $store->updateOrInsert([ 172 | '_id' => 1, 173 | 'text' => 'Hello from the SleekDB! This is as Clean as it gets!', 174 | 'author' => ['name' => 'George'] 175 | ], false); 176 | 177 | $store->updateOrInsert([ 178 | '_id' => 2, 179 | 'text' => 'Who really needs a PHP framework?', 180 | 'author' => ['name' => 'Brad'] 181 | ], false); 182 | 183 | $store->updateOrInsert([ 184 | '_id' => 3, 185 | 'text' => 'Hexagonal and Clean, this is so cool.', 186 | 'author' => ['name' => 'Sam'] 187 | ], false); 188 | 189 | $store->updateOrInsert([ 190 | '_id' => 4, 191 | 'text' => '', 192 | 'author' => ['name' => 'Peter'] 193 | ], false); 194 | 195 | } 196 | 197 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Application/ResponseEmitter.php: -------------------------------------------------------------------------------- 1 | sapiEmitter = new SapiEmitter(); 16 | } 17 | 18 | public function emit(ResponseInterface $response): void 19 | { 20 | $this->sapiEmitter->emit($response); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /src/ExampleApp/Infrastructure/Application/TemplatesProcessor.php: -------------------------------------------------------------------------------- 1 | loader = new FilesystemLoader($templatesDir); 16 | $this->twig = new Environment($this->loader); 17 | } 18 | 19 | public function processTemplate(string $template, $args): string 20 | { 21 | return $this->twig->render($template, $args); 22 | } 23 | } -------------------------------------------------------------------------------- /templates/edit-author.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example 6 | 7 | 8 | Specify greeting ID and new author: 9 |
10 |
11 | 12 | 13 |
14 | 15 | 16 |
17 | 18 |
19 | Back 20 |
21 | 22 | -------------------------------------------------------------------------------- /templates/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example 6 | 7 | 8 | {{ message }} 9 |
10 | Back 11 | 12 | -------------------------------------------------------------------------------- /templates/hello.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example 6 | 7 | 8 | {{ text }} 9 |
10 | Back 11 | 12 | -------------------------------------------------------------------------------- /templates/login-success.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example 6 | 7 | 8 | You have successfully logged in. 9 |
10 | Back 11 | 12 | -------------------------------------------------------------------------------- /templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example 6 | 7 | 8 | Login with credentials from
\ExampleApp\Infrastructure\Adapter\Config\ConfigAdapter
9 |
10 |
11 | 12 | 13 |
14 | 15 | 16 |
17 | 18 |
19 | Back 20 |
21 | 22 | -------------------------------------------------------------------------------- /templates/update-author-success.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example 6 | 7 | 8 | Author of the greeting #{{ greetingId }} has been successfully updated. 9 |
10 | Back 11 | 12 | -------------------------------------------------------------------------------- /templates/welcome.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example 6 | 7 | 8 | Hello. You are currently 9 | 10 | {% if userLoggedIn %} 11 | logged in as {{ username }}. 12 | {% endif %} 13 | 14 | {% if not userLoggedIn %} 15 | not logged in. 16 | {% endif %} 17 | 18 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tests/ExampleApp/Core/Model/GreetingTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(Greeting::class, $greeting); 21 | } 22 | 23 | /** 24 | * @return void 25 | * @throws Exception 26 | */ 27 | public function testInvalidGreetingIdThrowsInvalidDomainError(): void 28 | { 29 | $this->expectException(InvalidDomainObjectError::class); 30 | new Greeting(GreetingId::of(0), 'Test', new Author('Test')); 31 | } 32 | 33 | /** 34 | * @return void 35 | * @throws Exception 36 | */ 37 | public function testEmptyTextFailsWithInvalidDomainObjectError(): void 38 | { 39 | $this->expectException(InvalidDomainObjectError::class); 40 | new Greeting(GreetingId::of(1), '', new Author('Test')); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /tests/ExampleApp/Core/UserCase/SayHello/SayHelloUseCaseTest.php: -------------------------------------------------------------------------------- 1 | mockPresenter = Mockery::mock(SayHelloPresenterOutputPort::class); 28 | $this->mockGatewayOps = Mockery::mock(PersistenceGatewayOperationsOutputPort::class); 29 | } 30 | 31 | protected function tearDown(): void 32 | { 33 | Mockery::close(); 34 | } 35 | 36 | /** 37 | * @return void 38 | * @throws Exception 39 | */ 40 | public function testGreetUserSuccessfully(): void 41 | { 42 | 43 | // make a reference greeting 44 | $greeting = new Greeting(GreetingId::of(1), "Test", new Author('Test')); 45 | 46 | // return a reference greeting when the mock gateway is 47 | // called with an argument from an accepted range 48 | $this->mockGatewayOps->shouldReceive('obtainGreetingById') 49 | ->withArgs(function (GreetingId $arg) { 50 | return $this->inRange($arg->getId()); 51 | }) 52 | ->andReturn($greeting); 53 | 54 | // presenter should have been called to present the reference greeting 55 | $this->mockPresenter->shouldReceive('presentGreetingToUser') 56 | ->with($greeting); 57 | 58 | // presenter should not have been called to present any errors 59 | $this->shouldNotPresentAnyErrors(); 60 | 61 | // run the use case 62 | $this->runUseCase(); 63 | 64 | } 65 | 66 | /** 67 | * @return void 68 | * @throws Exception 69 | */ 70 | public function testShouldPresentErrorWhenGreetingNotFoundInStore(): void 71 | { 72 | // set up the mock to throw an exception when greeting could not 73 | // be found 74 | $this->mockGatewayOps->shouldReceive('obtainGreetingById') 75 | ->withAnyArgs() 76 | ->andThrow(GreetingPersistenceError::class); 77 | 78 | // presenter should have been called to present the right type of error 79 | $this->shouldPresentError(GreetingPersistenceError::class); 80 | 81 | // execute the use case 82 | $this->runUseCase(); 83 | 84 | } 85 | 86 | private function shouldNotPresentAnyErrors() 87 | { 88 | $this->mockPresenter->shouldNotReceive('presentError'); 89 | } 90 | 91 | private function shouldPresentError($errorType) 92 | { 93 | $this->mockPresenter->shouldReceive('presentError') 94 | ->withArgs(function ($e) use ($errorType) { 95 | return $e instanceof $errorType; 96 | }); 97 | } 98 | 99 | private function inRange(int $arg): bool 100 | { 101 | return $arg > 0 && $arg <= 5; 102 | } 103 | 104 | private function runUseCase(bool $withDefaultAssertion = true): void 105 | { 106 | // make an instance of the use case by providing mock presenter 107 | // and mock gateway 108 | $useCase = new SayHelloUseCase($this->mockPresenter, $this->mockGatewayOps); 109 | 110 | // execute the use case 111 | $useCase->greetUser(); 112 | 113 | if ($withDefaultAssertion) { 114 | $this->assertTrue(true); 115 | } 116 | } 117 | 118 | } --------------------------------------------------------------------------------