├── .gitignore
├── LICENSE
├── README.md
├── ch07
├── ea_extended
│ ├── InspectionExample.php
│ └── test.php
├── intelephense
│ └── DiagnosticsExample.php
├── phpcpd
│ └── src
│ │ ├── example.php
│ │ ├── example2.php
│ │ └── example3.php
├── phpmd
│ ├── example.php
│ ├── phpmd.baseline.xml
│ ├── phpmd.xml
│ ├── phpmd_report.html
│ └── src
│ │ ├── example.php
│ │ ├── example2.php
│ │ ├── example3.php
│ │ └── phpmd_suppress_example.php
├── phpstan
│ ├── phpstan-baseline.neon
│ ├── phpstan.neon
│ └── src
│ │ ├── phpstan_example.php
│ │ └── phpstan_example2.php
└── psalm
│ ├── psalm-baseline.xml
│ ├── psalm.xml
│ └── src
│ └── psalm_example.php
├── ch08
├── pdepend
│ └── src
│ │ ├── ccn.php
│ │ ├── ccn2.php
│ │ ├── npath.php
│ │ └── npath2.php
├── phploc
│ └── src
│ │ └── ccn.php
└── phpmetrics
│ └── src
│ └── ccn.php
├── ch09
├── composer.json
└── src
│ └── example.php
├── ch10
├── code_coverage
│ ├── .gitignore
│ ├── composer.json
│ ├── index.php
│ ├── phpunit.xml
│ ├── src
│ │ ├── MyApp.php
│ │ ├── MyOtherClass.php
│ │ ├── MyRepository.php
│ │ └── UntestedClass.php
│ └── tests
│ │ ├── MyAppTest.php
│ │ ├── MyOtherClassTest.php
│ │ ├── MyRepositoryTest.php
│ │ └── UselessTest.php
├── example-end-to-end-tests
│ └── login.spec.js
├── example-integration-tests
│ └── IntegrationTestExample.php
└── example-unit-tests
│ ├── index.php
│ ├── src
│ ├── MyApp.php
│ └── MyRepository.php
│ └── tests
│ ├── MyClassTest.php
│ └── MyRepositoryTest.php
├── ch11
└── example-application
│ ├── .github
│ └── workflows
│ │ └── ci.yml
│ ├── README.md
│ ├── captainhook.json
│ ├── composer.json
│ ├── composer.lock
│ ├── phpstan.neon
│ ├── phpunit.xml
│ ├── public
│ └── index.php
│ ├── src
│ ├── Controller
│ │ ├── ProductController.php
│ │ └── UserController.php
│ └── bootstrap.php
│ └── tests
│ ├── Api
│ └── ProductControllerTest.php
│ └── Unit
│ └── ProductControllerTest.php
├── ch12
└── design-patterns
│ ├── .DS_Store
│ ├── .gitignore
│ ├── README.md
│ ├── composer.json
│ ├── composer.lock
│ └── src
│ ├── DependencyInjection
│ ├── ConstructorInjection.php
│ ├── FileLogger.php
│ ├── InstantiationExample.php
│ ├── Logger.php
│ ├── SetterInjection.php
│ └── SetterInjectionFactory.php
│ ├── FactoryMethod
│ ├── AbstractWriter.php
│ ├── CsvEncoder.php
│ ├── CsvWriter.php
│ ├── Encoder.php
│ ├── Example.php
│ ├── JsonEncoder.php
│ └── JsonWriter.php
│ ├── Obvserver
│ ├── CustomerAccount.php
│ ├── CustomerAccountObserver.php
│ ├── MailService.php
│ ├── TightlyCoupledExample.php
│ └── bootstrap.php
│ ├── ServiceLocator
│ ├── ServiceLocator.php
│ ├── ServiceLocatorExample.php
│ └── SomeService.php
│ └── Singleton
│ └── SingletonExample.php
└── ch13
├── diagrams
└── mermaid.md
└── openapi
├── .gitignore
├── README.md
├── composer.json
├── openapi-annotations.yaml
├── openapi-attributes.json
├── openapi-attributes.yaml
└── src
├── Annotations
└── Controller
│ └── ProductController.php
└── Attributes
└── Controller
└── ProductController.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Packt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Clean Code in PHP
4 |
5 |
6 |
7 | This is the code repository for [Clean Code in PHP](https://www.packtpub.com/product/clean-code-in-php/9781804613870), published by Packt.
8 |
9 | **Expert tips and practices to write beautiful, human-friendly, and maintainable PHP**
10 |
11 | ## What is this book about?
12 | PHP is a beginner-friendly language, but also one that is rife with complaints of bad code, yet no clean code books are specific to PHP. Enter Clean Code in PHP. This book is a one-stop guide to learning the theory and best practices of clean code specific to real-world PHP app development environments.
13 |
14 | This book covers the following exciting features:
15 | * Build a solid foundation in clean coding to craft human-readable code
16 | * Understand metrics to determine the quality of your code
17 | * Get to grips with the basics of automated tests
18 | * Implement continuous integration for your PHP applications
19 | * Get an overview of software design patterns to help you write reusable code
20 | * Gain an understanding of coding guidelines and practices for working in teams
21 |
22 | If you feel this book is for you, get your [copy](https://www.amazon.com/Clean-Code-PHP-practices-maintainable/dp/1804613878) today!
23 |
24 |
25 | ## Instructions and Navigations
26 | All of the code is organized into folders. For example, Chapter07.
27 |
28 | The code will look like the following:
29 | ```
30 | 1) {
8 | return true;
9 | }
10 |
11 | return false;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch07/ea_extended/test.php:
--------------------------------------------------------------------------------
1 | checkGreaterThanOne(5);
--------------------------------------------------------------------------------
/ch07/intelephense/DiagnosticsExample.php:
--------------------------------------------------------------------------------
1 | usedAttribute == 2) {
12 | echo $this->usedAttribute;
13 | }
14 |
15 | $testInstance = new TestClass();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ch07/phpcpd/src/example.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ch07/phpmd/phpmd.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 | Rule set which contains all codesize and cleancode rules
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ch07/phpmd/phpmd_report.html:
--------------------------------------------------------------------------------
1 |
2 | PHPMD Report
3 |
4 |
5 | PHPMD Report
6 | Generated at 2022-04-27 08:18
7 | with PHP Mess Detector
8 | on PHP 8.0.8
9 | on curtis-desktop
10 |
11 | 2 problems found
Summary
By priorityCount | % | Priority |
---|
2 | 100.0 % | Top (1) |
12 | By rule setCount | % | Rule set |
---|
2 | 100.0 % | Clean Code Rules |
13 | By nameCount | % | Rule name |
---|
1 | 50.0 % | StaticAccess |
1 | 50.0 % | MissingImport |
14 | Details
15 |
21 | Show details ▼
22 | #1 Avoid using static access to class 'User' in method 'loadData'. (help) Top (1)
23 |
#2 Missing class import via use statement (line '28', column '21'). (help) Top (1)
24 |
--------------------------------------------------------------------------------
/ch07/phpmd/src/example.php:
--------------------------------------------------------------------------------
1 | find($id);
30 | }
31 | }
--------------------------------------------------------------------------------
/ch07/phpstan/phpstan-baseline.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | ignoreErrors:
3 | -
4 | message: "#^Method Vat\\:\\:getVat\\(\\) should return int but returns float\\.$#"
5 | count: 1
6 | path: src/phpstan_example.php
7 |
8 | -
9 | message: "#^Method OrderPosition\\:\\:getGrossPrice\\(\\) has no return type specified\\.$#"
10 | count: 1
11 | path: src/phpstan_example2.php
12 |
13 |
--------------------------------------------------------------------------------
/ch07/phpstan/phpstan.neon:
--------------------------------------------------------------------------------
1 | # includes:
2 | # - phpstan-baseline.neon
3 | parameters:
4 | level: 6
5 | paths:
6 | - src
--------------------------------------------------------------------------------
/ch07/phpstan/src/phpstan_example.php:
--------------------------------------------------------------------------------
1 | vat;
10 | }
11 | }
12 |
13 | class OrderPosition
14 | {
15 | public function getGrossPrice(float $netPrice): float
16 | {
17 | $vatModel = new Vat();
18 | $vat = $vatModel->getVat();
19 |
20 | return $netPrice * (1 + $vat);
21 | }
22 | }
23 |
24 | $orderPosition = new OrderPosition();
25 | echo $orderPosition->getGrossPrice(100);
--------------------------------------------------------------------------------
/ch07/phpstan/src/phpstan_example2.php:
--------------------------------------------------------------------------------
1 | vat;
10 | }
11 | }
12 |
13 | class OrderPosition
14 | {
15 | public function getGrossPrice(float $netPrice)
16 | {
17 | $vatModel = new Vat();
18 | $vat = $vatModel->getVat();
19 |
20 | return $netPrice * (1 + $vat);
21 | }
22 | }
23 |
24 | $orderPosition = new OrderPosition();
25 | echo $orderPosition->getGrossPrice(100);
--------------------------------------------------------------------------------
/ch07/psalm/psalm-baseline.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ch07/psalm/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
--------------------------------------------------------------------------------
/ch07/psalm/src/psalm_example.php:
--------------------------------------------------------------------------------
1 | vat;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ch08/pdepend/src/ccn.php:
--------------------------------------------------------------------------------
1 | $b) {
14 | echo "3";
15 | } else {
16 | echo "4";
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/ch08/pdepend/src/ccn2.php:
--------------------------------------------------------------------------------
1 | $b) {
14 | echo "3";
15 | } else {
16 | echo "4";
17 | }
18 |
19 | if ($a == $b) {
20 | echo "5";
21 | } else {
22 | echo "6";
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/ch08/pdepend/src/npath.php:
--------------------------------------------------------------------------------
1 | 10) {
9 | echo 1;
10 | } else {
11 | echo 2;
12 | }
13 | if ($a > $b) {
14 | echo 3;
15 | } else {
16 | echo 4;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ch08/pdepend/src/npath2.php:
--------------------------------------------------------------------------------
1 | 10) {
8 | echo 1;
9 | } else {
10 | echo 2;
11 | }
12 | if ($a > $b) {
13 | echo 3;
14 | } else {
15 | echo 4;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch08/phploc/src/ccn.php:
--------------------------------------------------------------------------------
1 | vat;
10 | }
11 | }
12 |
13 | class OrderPosition
14 | {
15 | public function getGrossPrice(float $netPrice): float
16 | {
17 | $vatModel = new Vat();
18 | $vat = $vatModel->getVat();
19 |
20 | return $netPrice * (1 + $vat);
21 | }
22 | }
23 |
24 | $orderPosition = new OrderPosition();
25 | echo $orderPosition->getGrossPrice(100);
26 |
--------------------------------------------------------------------------------
/ch10/code_coverage/.gitignore:
--------------------------------------------------------------------------------
1 | .phpunit.cache
2 | .phive
3 | reports
4 |
--------------------------------------------------------------------------------
/ch10/code_coverage/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require-dev": {
3 | "phpunit/phpunit": "^9.5"
4 | },
5 | "autoload-dev": {
6 | "psr-4": {
7 | "CodeCoverageExample\\": "src/",
8 | "CodeCoverageExampleTest\\": "tests/"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ch10/code_coverage/index.php:
--------------------------------------------------------------------------------
1 | run();
--------------------------------------------------------------------------------
/ch10/code_coverage/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | tests
10 |
11 |
12 |
13 |
14 | src
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ch10/code_coverage/src/MyApp.php:
--------------------------------------------------------------------------------
1 | myRepository->getData();
17 |
18 | return $dataArray['value_1'] . $dataArray['value_2'];
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch10/code_coverage/src/MyOtherClass.php:
--------------------------------------------------------------------------------
1 | 0) {
12 | return $a + 1;
13 | }
14 |
15 | if ($a === 0) {
16 | return $a;
17 | }
18 |
19 | return $a - 1;
20 |
21 | echo "nothing";
22 | }
23 |
24 | public function gni()
25 | {
26 | echo "nothing";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ch10/code_coverage/src/MyRepository.php:
--------------------------------------------------------------------------------
1 | 'some data...',
13 | 'val2' => 'and some more data'
14 | ];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch10/code_coverage/src/UntestedClass.php:
--------------------------------------------------------------------------------
1 | myRepository->getData();
12 |
13 | return $dataArray['value_1'] . $dataArray['value_2'];
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ch10/code_coverage/tests/MyAppTest.php:
--------------------------------------------------------------------------------
1 | createMock(MyRepository::class);
19 | $repositoryMock
20 | ->expects($this->once())
21 | ->method('getData')
22 | ->willReturn([
23 | 'value_1' => 'a',
24 | 'value_2' => 'b'
25 | ]);
26 |
27 | $appTest = new MyApp($repositoryMock);
28 |
29 | $result = $appTest->run();
30 |
31 | $this->assertEquals('ab', $result);
32 | }
33 | }
--------------------------------------------------------------------------------
/ch10/code_coverage/tests/MyOtherClassTest.php:
--------------------------------------------------------------------------------
1 | doSomething(1);
20 |
21 | $this->assertEquals(2, $result);
22 | }
23 | }
--------------------------------------------------------------------------------
/ch10/code_coverage/tests/MyRepositoryTest.php:
--------------------------------------------------------------------------------
1 | getData();
20 |
21 | $this->assertIsArray($result);
22 | $this->assertCount(2, $result);
23 | }
24 | }
--------------------------------------------------------------------------------
/ch10/code_coverage/tests/UselessTest.php:
--------------------------------------------------------------------------------
1 | createMock(MyRepository::class);
18 | $repositoryMock
19 | ->method('getData')
20 | ->willReturn([
21 | 'value_1' => 'a',
22 | 'value_2' => 'b'
23 | ]);
24 |
25 | $this->assertEquals(
26 | [
27 | 'value_1' => 'a',
28 | 'value_2' => 'b'
29 | ],
30 | $repositoryMock->getData()
31 | );
32 | }
33 | }
--------------------------------------------------------------------------------
/ch10/example-end-to-end-tests/login.spec.js:
--------------------------------------------------------------------------------
1 | describe('Application Login', function () {
2 | it('successfully logs in', function () {
3 | cy.visit('http://localhost:8000/login')
4 |
5 | cy.get('#username')
6 | .type('test@test.com')
7 |
8 | cy.get('#password')
9 | .type('supersecret')
10 |
11 | cy.get('#submit')
12 | .click()
13 |
14 | cy.url()
15 | .should('contain', 'http://localhost:8000/home')
16 | })
17 | })
--------------------------------------------------------------------------------
/ch10/example-integration-tests/IntegrationTestExample.php:
--------------------------------------------------------------------------------
1 | setId(123);
11 | $product->setName('USB Coffee Maker');
12 | $product->save();
13 |
14 | $this->tester->seeInDatabase(
15 | 'products',
16 | ['id' => 123, 'name' => 'USB Coffee Maker' ]
17 | );
18 | }
19 | }
--------------------------------------------------------------------------------
/ch10/example-unit-tests/index.php:
--------------------------------------------------------------------------------
1 | run();
--------------------------------------------------------------------------------
/ch10/example-unit-tests/src/MyApp.php:
--------------------------------------------------------------------------------
1 | myRepository->getData();
17 |
18 | return $dataArray['value_1'] . $dataArray['value_2'];
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch10/example-unit-tests/src/MyRepository.php:
--------------------------------------------------------------------------------
1 | 'some data...',
13 | 'val2' => 'and some more data'
14 | ];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch10/example-unit-tests/tests/MyClassTest.php:
--------------------------------------------------------------------------------
1 | createMock(MyRepository::class);
16 | $repositoryMock
17 | ->expects($this->once())
18 | ->method('getData')
19 | ->willReturn([
20 | 'value_1' => 'a',
21 | 'value_2' => 'b'
22 | ]);
23 |
24 | $appTest = new MyApp($repositoryMock);
25 |
26 | $result = $appTest->run();
27 |
28 | $this->assertEquals('ab', $result);
29 | }
30 | }
--------------------------------------------------------------------------------
/ch10/example-unit-tests/tests/MyRepositoryTest.php:
--------------------------------------------------------------------------------
1 | getData();
17 |
18 | $this->assertIsArray($result);
19 | $this->assertCount(2, $result);
20 | }
21 | }
--------------------------------------------------------------------------------
/ch11/example-application/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Continuous Integration
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches:
7 | - main
8 | pull_request:
9 |
10 | jobs:
11 | pipeline:
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | ###################
16 | # Stage 1 - Build #
17 | ###################
18 | - name: Checkout latest revision
19 | uses: actions/checkout@v3
20 |
21 | - name: Install PHP
22 | uses: shivammathur/setup-php@v2
23 | with:
24 | php-version: '8.1'
25 | coverage: pcov
26 |
27 | - name: Get composer cache directory
28 | id: composer-cache
29 | run: echo "::set-output name=dir::$(composer config cache-files-dir)"
30 |
31 | - name: Cache dependencies
32 | uses: actions/cache@v2
33 | with:
34 | path: ${{ steps.composer-cache.outputs.dir }}
35 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
36 | restore-keys: ${{ runner.os }}-composer-
37 |
38 | - name: Install composer dependencies
39 | run: composer install
40 |
41 | - name: Start PHP built-in webserver
42 | run: php -S localhost:8000 -t public &
43 |
44 | ###########################
45 | # Stage 2 - Code Analysis #
46 | ###########################
47 | - name: Code Style Fixer
48 | run: vendor/bin/php-cs-fixer fix --dry-run
49 |
50 | - name: Static Code Analysis
51 | run: vendor/bin/phpstan
52 |
53 | ###################
54 | # Stage 3 - Tests #
55 | ###################
56 | - name: Unit Tests
57 | run: vendor/bin/phpunit --testsuite Unit
58 |
59 | - name: Integration Tests
60 | run: vendor/bin/phpunit --testsuite Api
61 |
62 | ####################
63 | # Stage 4 - Deploy #
64 | ####################
65 | - name: Remove dev dependencies
66 | run: composer install --no-dev --optimize-autoloader
67 |
68 | - name: Create release artifact
69 | uses: actions/upload-artifact@v2
70 | with:
71 | name: release
72 | path: |
73 | public/
74 | src/
75 | vendor/
76 |
77 | - name: Create reports artifact
78 | uses: actions/upload-artifact@v2
79 | with:
80 | name: reports
81 | path: reports/
82 |
--------------------------------------------------------------------------------
/ch11/example-application/README.md:
--------------------------------------------------------------------------------
1 | # Continuous Integration example
2 |
3 | This is a simple example application to demonstrate
4 | 1. how to build a Continuous Integration pipeline with GitHub Actions
5 | 2. how to set up a local pipeline using CaptainHook
6 |
7 | ## Installation
8 | To install it locally, simply run
9 |
10 | `composer install`
11 |
12 | ## Hot to test GitHub Actions
13 |
14 | To test the GitHub Actions pipeline, please create a separate GitHub repository from the project folder. This is necessary, because GitHub requires the `.github/worfklows` folder to be located in the project root.
15 |
16 | ## How to test CaptainHook
17 |
18 | After running `composer install`, the `pre-commit` hook is already installed. To test it, simply change a PHP file, add it using `git add`, and commit the changes using `git commit`.
--------------------------------------------------------------------------------
/ch11/example-application/captainhook.json:
--------------------------------------------------------------------------------
1 | {
2 | "config": {
3 | "fail-on-first-error": true
4 | },
5 | "pre-commit": {
6 | "enabled": true,
7 | "actions": [
8 | {
9 | "action": "vendor/bin/php-cs-fixer fix {$STAGED_FILES|of-type:php} --dry-run"
10 | },
11 | {
12 | "action": "vendor/bin/phpstan analyse {$STAGED_FILES|of-type:php}"
13 | }
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch11/example-application/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clean-code-book/github-actions-pipeline",
3 | "description": "Example setup of a simple GitHub Actions pipeline",
4 | "type": "project",
5 | "require": {
6 | "php": ">= 8.1",
7 | "league/route": "^5.1",
8 | "laminas/laminas-diactoros": "^2.13",
9 | "laminas/laminas-httphandlerrunner": "^2.1"
10 | },
11 | "require-dev": {
12 | "phpunit/phpunit": "^9.5",
13 | "phpstan/phpstan": "^1.8",
14 | "friendsofphp/php-cs-fixer": "^3.8",
15 | "guzzlehttp/guzzle": "^7.4",
16 | "captainhook/captainhook": "^5.10"
17 | },
18 | "autoload": {
19 | "psr-4": {
20 | "GitHubActionsExample\\":"src/"
21 | }
22 | },
23 | "scripts": {
24 | "post-autoload-dump": [
25 | "if [ -e vendor/bin/captainhook ]; then vendor/bin/captainhook install -f -s; fi"
26 | ]
27 | },
28 | "authors": [
29 | {
30 | "name": "Carsten Windler",
31 | "email": "carsten@carstenwindler.de"
32 | }
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/ch11/example-application/phpstan.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | level: 5
3 | paths:
4 | - src
5 |
--------------------------------------------------------------------------------
/ch11/example-application/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 | tests/Api
18 |
19 |
20 | tests/Unit
21 |
22 |
23 |
24 |
25 |
26 | src
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ch11/example-application/public/index.php:
--------------------------------------------------------------------------------
1 | 1,
14 | 'name' => 'Foo product',
15 | ]
16 | ];
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch11/example-application/src/Controller/UserController.php:
--------------------------------------------------------------------------------
1 | 1,
14 | 'name' => 'Foo bar',
15 | ]
16 | ];
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch11/example-application/src/bootstrap.php:
--------------------------------------------------------------------------------
1 | setStrategy($strategy);
19 |
20 | // Define routes
21 | $router->map(
22 | 'GET',
23 | '/products',
24 | [
25 | ProductController::class,
26 | 'get'
27 | ]
28 | );
29 |
30 | $router->map(
31 | 'GET',
32 | '/users',
33 | [
34 | UserController::class,
35 | 'get'
36 | ]
37 | );
38 |
39 | // Dispatch the request to receive a response object
40 | $response = $router->dispatch($request);
41 |
42 | // Send the response
43 | (new Laminas\HttpHandlerRunner\Emitter\SapiEmitter())->emit($response);
44 |
--------------------------------------------------------------------------------
/ch11/example-application/tests/Api/ProductControllerTest.php:
--------------------------------------------------------------------------------
1 | getBody()->getContents(),
22 | true,
23 | 512,
24 | JSON_THROW_ON_ERROR
25 | );
26 | }
27 |
28 | public function setUp(): void
29 | {
30 | $this->client = new Client();
31 | }
32 |
33 | public function testGetProducts()
34 | {
35 | $response = $this->client->request(
36 | 'GET',
37 | 'http://localhost:8000/products'
38 | );
39 |
40 | $this->assertEquals(
41 | 200,
42 | $response->getStatusCode()
43 | );
44 |
45 | $this->assertEquals(
46 | [
47 | [
48 | 'id' => 1,
49 | 'name' => 'Foo product',
50 | ]
51 | ],
52 | $this->getResponseAsArray($response)
53 | );
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ch11/example-application/tests/Unit/ProductControllerTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(
20 | [
21 | [
22 | 'id' => 1,
23 | 'name' => 'Foo product',
24 | ]
25 | ],
26 | $productController->get()
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ch12/design-patterns/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Clean-Code-in-PHP/4a0c2323a62450f6cc82ff8dc861e1a5d51b9ed9/ch12/design-patterns/.DS_Store
--------------------------------------------------------------------------------
/ch12/design-patterns/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
--------------------------------------------------------------------------------
/ch12/design-patterns/README.md:
--------------------------------------------------------------------------------
1 | # Design Patterns
2 |
3 | This project contains no usable code, only the examples from chapter 12 of our book.
4 |
5 | ## Installation
6 |
7 | Run `composer install`. No more action needed.
8 |
9 | ## Running the examples
10 |
11 | Every
12 |
13 | TODO FORMAST PSR-12!!!!!!!!!!!!!!!!!!!
--------------------------------------------------------------------------------
/ch12/design-patterns/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clean-code-book/design-patterns",
3 | "description": "Example code for the design patterns discussed in our book",
4 | "type": "project",
5 | "autoload": {
6 | "psr-4": {
7 | "DesignPatterns\\": "src/"
8 | }
9 | },
10 | "authors": [
11 | {
12 | "name": "Carsten Windler",
13 | "email": "carsten@carstenwindler.de"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/ch12/design-patterns/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": "f431e700213d937b59fdd6e5a31e54a7",
8 | "packages": [
9 | {
10 | "name": "doctrine/instantiator",
11 | "version": "1.4.1",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/doctrine/instantiator.git",
15 | "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc",
20 | "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "php": "^7.1 || ^8.0"
25 | },
26 | "require-dev": {
27 | "doctrine/coding-standard": "^9",
28 | "ext-pdo": "*",
29 | "ext-phar": "*",
30 | "phpbench/phpbench": "^0.16 || ^1",
31 | "phpstan/phpstan": "^1.4",
32 | "phpstan/phpstan-phpunit": "^1",
33 | "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
34 | "vimeo/psalm": "^4.22"
35 | },
36 | "type": "library",
37 | "autoload": {
38 | "psr-4": {
39 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
40 | }
41 | },
42 | "notification-url": "https://packagist.org/downloads/",
43 | "license": [
44 | "MIT"
45 | ],
46 | "authors": [
47 | {
48 | "name": "Marco Pivetta",
49 | "email": "ocramius@gmail.com",
50 | "homepage": "https://ocramius.github.io/"
51 | }
52 | ],
53 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
54 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
55 | "keywords": [
56 | "constructor",
57 | "instantiate"
58 | ],
59 | "support": {
60 | "issues": "https://github.com/doctrine/instantiator/issues",
61 | "source": "https://github.com/doctrine/instantiator/tree/1.4.1"
62 | },
63 | "funding": [
64 | {
65 | "url": "https://www.doctrine-project.org/sponsorship.html",
66 | "type": "custom"
67 | },
68 | {
69 | "url": "https://www.patreon.com/phpdoctrine",
70 | "type": "patreon"
71 | },
72 | {
73 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
74 | "type": "tidelift"
75 | }
76 | ],
77 | "time": "2022-03-03T08:28:38+00:00"
78 | },
79 | {
80 | "name": "myclabs/deep-copy",
81 | "version": "1.11.0",
82 | "source": {
83 | "type": "git",
84 | "url": "https://github.com/myclabs/DeepCopy.git",
85 | "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
86 | },
87 | "dist": {
88 | "type": "zip",
89 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
90 | "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
91 | "shasum": ""
92 | },
93 | "require": {
94 | "php": "^7.1 || ^8.0"
95 | },
96 | "conflict": {
97 | "doctrine/collections": "<1.6.8",
98 | "doctrine/common": "<2.13.3 || >=3,<3.2.2"
99 | },
100 | "require-dev": {
101 | "doctrine/collections": "^1.6.8",
102 | "doctrine/common": "^2.13.3 || ^3.2.2",
103 | "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
104 | },
105 | "type": "library",
106 | "autoload": {
107 | "files": [
108 | "src/DeepCopy/deep_copy.php"
109 | ],
110 | "psr-4": {
111 | "DeepCopy\\": "src/DeepCopy/"
112 | }
113 | },
114 | "notification-url": "https://packagist.org/downloads/",
115 | "license": [
116 | "MIT"
117 | ],
118 | "description": "Create deep copies (clones) of your objects",
119 | "keywords": [
120 | "clone",
121 | "copy",
122 | "duplicate",
123 | "object",
124 | "object graph"
125 | ],
126 | "support": {
127 | "issues": "https://github.com/myclabs/DeepCopy/issues",
128 | "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
129 | },
130 | "funding": [
131 | {
132 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
133 | "type": "tidelift"
134 | }
135 | ],
136 | "time": "2022-03-03T13:19:32+00:00"
137 | },
138 | {
139 | "name": "nikic/php-parser",
140 | "version": "v4.14.0",
141 | "source": {
142 | "type": "git",
143 | "url": "https://github.com/nikic/PHP-Parser.git",
144 | "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1"
145 | },
146 | "dist": {
147 | "type": "zip",
148 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1",
149 | "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1",
150 | "shasum": ""
151 | },
152 | "require": {
153 | "ext-tokenizer": "*",
154 | "php": ">=7.0"
155 | },
156 | "require-dev": {
157 | "ircmaxell/php-yacc": "^0.0.7",
158 | "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
159 | },
160 | "bin": [
161 | "bin/php-parse"
162 | ],
163 | "type": "library",
164 | "extra": {
165 | "branch-alias": {
166 | "dev-master": "4.9-dev"
167 | }
168 | },
169 | "autoload": {
170 | "psr-4": {
171 | "PhpParser\\": "lib/PhpParser"
172 | }
173 | },
174 | "notification-url": "https://packagist.org/downloads/",
175 | "license": [
176 | "BSD-3-Clause"
177 | ],
178 | "authors": [
179 | {
180 | "name": "Nikita Popov"
181 | }
182 | ],
183 | "description": "A PHP parser written in PHP",
184 | "keywords": [
185 | "parser",
186 | "php"
187 | ],
188 | "support": {
189 | "issues": "https://github.com/nikic/PHP-Parser/issues",
190 | "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0"
191 | },
192 | "time": "2022-05-31T20:59:12+00:00"
193 | },
194 | {
195 | "name": "phar-io/manifest",
196 | "version": "2.0.3",
197 | "source": {
198 | "type": "git",
199 | "url": "https://github.com/phar-io/manifest.git",
200 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
201 | },
202 | "dist": {
203 | "type": "zip",
204 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
205 | "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
206 | "shasum": ""
207 | },
208 | "require": {
209 | "ext-dom": "*",
210 | "ext-phar": "*",
211 | "ext-xmlwriter": "*",
212 | "phar-io/version": "^3.0.1",
213 | "php": "^7.2 || ^8.0"
214 | },
215 | "type": "library",
216 | "extra": {
217 | "branch-alias": {
218 | "dev-master": "2.0.x-dev"
219 | }
220 | },
221 | "autoload": {
222 | "classmap": [
223 | "src/"
224 | ]
225 | },
226 | "notification-url": "https://packagist.org/downloads/",
227 | "license": [
228 | "BSD-3-Clause"
229 | ],
230 | "authors": [
231 | {
232 | "name": "Arne Blankerts",
233 | "email": "arne@blankerts.de",
234 | "role": "Developer"
235 | },
236 | {
237 | "name": "Sebastian Heuer",
238 | "email": "sebastian@phpeople.de",
239 | "role": "Developer"
240 | },
241 | {
242 | "name": "Sebastian Bergmann",
243 | "email": "sebastian@phpunit.de",
244 | "role": "Developer"
245 | }
246 | ],
247 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
248 | "support": {
249 | "issues": "https://github.com/phar-io/manifest/issues",
250 | "source": "https://github.com/phar-io/manifest/tree/2.0.3"
251 | },
252 | "time": "2021-07-20T11:28:43+00:00"
253 | },
254 | {
255 | "name": "phar-io/version",
256 | "version": "3.2.1",
257 | "source": {
258 | "type": "git",
259 | "url": "https://github.com/phar-io/version.git",
260 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
261 | },
262 | "dist": {
263 | "type": "zip",
264 | "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
265 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
266 | "shasum": ""
267 | },
268 | "require": {
269 | "php": "^7.2 || ^8.0"
270 | },
271 | "type": "library",
272 | "autoload": {
273 | "classmap": [
274 | "src/"
275 | ]
276 | },
277 | "notification-url": "https://packagist.org/downloads/",
278 | "license": [
279 | "BSD-3-Clause"
280 | ],
281 | "authors": [
282 | {
283 | "name": "Arne Blankerts",
284 | "email": "arne@blankerts.de",
285 | "role": "Developer"
286 | },
287 | {
288 | "name": "Sebastian Heuer",
289 | "email": "sebastian@phpeople.de",
290 | "role": "Developer"
291 | },
292 | {
293 | "name": "Sebastian Bergmann",
294 | "email": "sebastian@phpunit.de",
295 | "role": "Developer"
296 | }
297 | ],
298 | "description": "Library for handling version information and constraints",
299 | "support": {
300 | "issues": "https://github.com/phar-io/version/issues",
301 | "source": "https://github.com/phar-io/version/tree/3.2.1"
302 | },
303 | "time": "2022-02-21T01:04:05+00:00"
304 | },
305 | {
306 | "name": "phpdocumentor/reflection-common",
307 | "version": "2.2.0",
308 | "source": {
309 | "type": "git",
310 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
311 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
312 | },
313 | "dist": {
314 | "type": "zip",
315 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
316 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
317 | "shasum": ""
318 | },
319 | "require": {
320 | "php": "^7.2 || ^8.0"
321 | },
322 | "type": "library",
323 | "extra": {
324 | "branch-alias": {
325 | "dev-2.x": "2.x-dev"
326 | }
327 | },
328 | "autoload": {
329 | "psr-4": {
330 | "phpDocumentor\\Reflection\\": "src/"
331 | }
332 | },
333 | "notification-url": "https://packagist.org/downloads/",
334 | "license": [
335 | "MIT"
336 | ],
337 | "authors": [
338 | {
339 | "name": "Jaap van Otterdijk",
340 | "email": "opensource@ijaap.nl"
341 | }
342 | ],
343 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
344 | "homepage": "http://www.phpdoc.org",
345 | "keywords": [
346 | "FQSEN",
347 | "phpDocumentor",
348 | "phpdoc",
349 | "reflection",
350 | "static analysis"
351 | ],
352 | "support": {
353 | "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
354 | "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
355 | },
356 | "time": "2020-06-27T09:03:43+00:00"
357 | },
358 | {
359 | "name": "phpdocumentor/reflection-docblock",
360 | "version": "5.3.0",
361 | "source": {
362 | "type": "git",
363 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
364 | "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
365 | },
366 | "dist": {
367 | "type": "zip",
368 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
369 | "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
370 | "shasum": ""
371 | },
372 | "require": {
373 | "ext-filter": "*",
374 | "php": "^7.2 || ^8.0",
375 | "phpdocumentor/reflection-common": "^2.2",
376 | "phpdocumentor/type-resolver": "^1.3",
377 | "webmozart/assert": "^1.9.1"
378 | },
379 | "require-dev": {
380 | "mockery/mockery": "~1.3.2",
381 | "psalm/phar": "^4.8"
382 | },
383 | "type": "library",
384 | "extra": {
385 | "branch-alias": {
386 | "dev-master": "5.x-dev"
387 | }
388 | },
389 | "autoload": {
390 | "psr-4": {
391 | "phpDocumentor\\Reflection\\": "src"
392 | }
393 | },
394 | "notification-url": "https://packagist.org/downloads/",
395 | "license": [
396 | "MIT"
397 | ],
398 | "authors": [
399 | {
400 | "name": "Mike van Riel",
401 | "email": "me@mikevanriel.com"
402 | },
403 | {
404 | "name": "Jaap van Otterdijk",
405 | "email": "account@ijaap.nl"
406 | }
407 | ],
408 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
409 | "support": {
410 | "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
411 | "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
412 | },
413 | "time": "2021-10-19T17:43:47+00:00"
414 | },
415 | {
416 | "name": "phpdocumentor/type-resolver",
417 | "version": "1.6.1",
418 | "source": {
419 | "type": "git",
420 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
421 | "reference": "77a32518733312af16a44300404e945338981de3"
422 | },
423 | "dist": {
424 | "type": "zip",
425 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3",
426 | "reference": "77a32518733312af16a44300404e945338981de3",
427 | "shasum": ""
428 | },
429 | "require": {
430 | "php": "^7.2 || ^8.0",
431 | "phpdocumentor/reflection-common": "^2.0"
432 | },
433 | "require-dev": {
434 | "ext-tokenizer": "*",
435 | "psalm/phar": "^4.8"
436 | },
437 | "type": "library",
438 | "extra": {
439 | "branch-alias": {
440 | "dev-1.x": "1.x-dev"
441 | }
442 | },
443 | "autoload": {
444 | "psr-4": {
445 | "phpDocumentor\\Reflection\\": "src"
446 | }
447 | },
448 | "notification-url": "https://packagist.org/downloads/",
449 | "license": [
450 | "MIT"
451 | ],
452 | "authors": [
453 | {
454 | "name": "Mike van Riel",
455 | "email": "me@mikevanriel.com"
456 | }
457 | ],
458 | "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
459 | "support": {
460 | "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
461 | "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1"
462 | },
463 | "time": "2022-03-15T21:29:03+00:00"
464 | },
465 | {
466 | "name": "phpspec/prophecy",
467 | "version": "v1.15.0",
468 | "source": {
469 | "type": "git",
470 | "url": "https://github.com/phpspec/prophecy.git",
471 | "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
472 | },
473 | "dist": {
474 | "type": "zip",
475 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
476 | "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
477 | "shasum": ""
478 | },
479 | "require": {
480 | "doctrine/instantiator": "^1.2",
481 | "php": "^7.2 || ~8.0, <8.2",
482 | "phpdocumentor/reflection-docblock": "^5.2",
483 | "sebastian/comparator": "^3.0 || ^4.0",
484 | "sebastian/recursion-context": "^3.0 || ^4.0"
485 | },
486 | "require-dev": {
487 | "phpspec/phpspec": "^6.0 || ^7.0",
488 | "phpunit/phpunit": "^8.0 || ^9.0"
489 | },
490 | "type": "library",
491 | "extra": {
492 | "branch-alias": {
493 | "dev-master": "1.x-dev"
494 | }
495 | },
496 | "autoload": {
497 | "psr-4": {
498 | "Prophecy\\": "src/Prophecy"
499 | }
500 | },
501 | "notification-url": "https://packagist.org/downloads/",
502 | "license": [
503 | "MIT"
504 | ],
505 | "authors": [
506 | {
507 | "name": "Konstantin Kudryashov",
508 | "email": "ever.zet@gmail.com",
509 | "homepage": "http://everzet.com"
510 | },
511 | {
512 | "name": "Marcello Duarte",
513 | "email": "marcello.duarte@gmail.com"
514 | }
515 | ],
516 | "description": "Highly opinionated mocking framework for PHP 5.3+",
517 | "homepage": "https://github.com/phpspec/prophecy",
518 | "keywords": [
519 | "Double",
520 | "Dummy",
521 | "fake",
522 | "mock",
523 | "spy",
524 | "stub"
525 | ],
526 | "support": {
527 | "issues": "https://github.com/phpspec/prophecy/issues",
528 | "source": "https://github.com/phpspec/prophecy/tree/v1.15.0"
529 | },
530 | "time": "2021-12-08T12:19:24+00:00"
531 | },
532 | {
533 | "name": "phpunit/php-code-coverage",
534 | "version": "9.2.15",
535 | "source": {
536 | "type": "git",
537 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
538 | "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f"
539 | },
540 | "dist": {
541 | "type": "zip",
542 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f",
543 | "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f",
544 | "shasum": ""
545 | },
546 | "require": {
547 | "ext-dom": "*",
548 | "ext-libxml": "*",
549 | "ext-xmlwriter": "*",
550 | "nikic/php-parser": "^4.13.0",
551 | "php": ">=7.3",
552 | "phpunit/php-file-iterator": "^3.0.3",
553 | "phpunit/php-text-template": "^2.0.2",
554 | "sebastian/code-unit-reverse-lookup": "^2.0.2",
555 | "sebastian/complexity": "^2.0",
556 | "sebastian/environment": "^5.1.2",
557 | "sebastian/lines-of-code": "^1.0.3",
558 | "sebastian/version": "^3.0.1",
559 | "theseer/tokenizer": "^1.2.0"
560 | },
561 | "require-dev": {
562 | "phpunit/phpunit": "^9.3"
563 | },
564 | "suggest": {
565 | "ext-pcov": "*",
566 | "ext-xdebug": "*"
567 | },
568 | "type": "library",
569 | "extra": {
570 | "branch-alias": {
571 | "dev-master": "9.2-dev"
572 | }
573 | },
574 | "autoload": {
575 | "classmap": [
576 | "src/"
577 | ]
578 | },
579 | "notification-url": "https://packagist.org/downloads/",
580 | "license": [
581 | "BSD-3-Clause"
582 | ],
583 | "authors": [
584 | {
585 | "name": "Sebastian Bergmann",
586 | "email": "sebastian@phpunit.de",
587 | "role": "lead"
588 | }
589 | ],
590 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
591 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
592 | "keywords": [
593 | "coverage",
594 | "testing",
595 | "xunit"
596 | ],
597 | "support": {
598 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
599 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15"
600 | },
601 | "funding": [
602 | {
603 | "url": "https://github.com/sebastianbergmann",
604 | "type": "github"
605 | }
606 | ],
607 | "time": "2022-03-07T09:28:20+00:00"
608 | },
609 | {
610 | "name": "phpunit/php-file-iterator",
611 | "version": "3.0.6",
612 | "source": {
613 | "type": "git",
614 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
615 | "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
616 | },
617 | "dist": {
618 | "type": "zip",
619 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
620 | "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
621 | "shasum": ""
622 | },
623 | "require": {
624 | "php": ">=7.3"
625 | },
626 | "require-dev": {
627 | "phpunit/phpunit": "^9.3"
628 | },
629 | "type": "library",
630 | "extra": {
631 | "branch-alias": {
632 | "dev-master": "3.0-dev"
633 | }
634 | },
635 | "autoload": {
636 | "classmap": [
637 | "src/"
638 | ]
639 | },
640 | "notification-url": "https://packagist.org/downloads/",
641 | "license": [
642 | "BSD-3-Clause"
643 | ],
644 | "authors": [
645 | {
646 | "name": "Sebastian Bergmann",
647 | "email": "sebastian@phpunit.de",
648 | "role": "lead"
649 | }
650 | ],
651 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
652 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
653 | "keywords": [
654 | "filesystem",
655 | "iterator"
656 | ],
657 | "support": {
658 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
659 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
660 | },
661 | "funding": [
662 | {
663 | "url": "https://github.com/sebastianbergmann",
664 | "type": "github"
665 | }
666 | ],
667 | "time": "2021-12-02T12:48:52+00:00"
668 | },
669 | {
670 | "name": "phpunit/php-invoker",
671 | "version": "3.1.1",
672 | "source": {
673 | "type": "git",
674 | "url": "https://github.com/sebastianbergmann/php-invoker.git",
675 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
676 | },
677 | "dist": {
678 | "type": "zip",
679 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
680 | "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
681 | "shasum": ""
682 | },
683 | "require": {
684 | "php": ">=7.3"
685 | },
686 | "require-dev": {
687 | "ext-pcntl": "*",
688 | "phpunit/phpunit": "^9.3"
689 | },
690 | "suggest": {
691 | "ext-pcntl": "*"
692 | },
693 | "type": "library",
694 | "extra": {
695 | "branch-alias": {
696 | "dev-master": "3.1-dev"
697 | }
698 | },
699 | "autoload": {
700 | "classmap": [
701 | "src/"
702 | ]
703 | },
704 | "notification-url": "https://packagist.org/downloads/",
705 | "license": [
706 | "BSD-3-Clause"
707 | ],
708 | "authors": [
709 | {
710 | "name": "Sebastian Bergmann",
711 | "email": "sebastian@phpunit.de",
712 | "role": "lead"
713 | }
714 | ],
715 | "description": "Invoke callables with a timeout",
716 | "homepage": "https://github.com/sebastianbergmann/php-invoker/",
717 | "keywords": [
718 | "process"
719 | ],
720 | "support": {
721 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
722 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
723 | },
724 | "funding": [
725 | {
726 | "url": "https://github.com/sebastianbergmann",
727 | "type": "github"
728 | }
729 | ],
730 | "time": "2020-09-28T05:58:55+00:00"
731 | },
732 | {
733 | "name": "phpunit/php-text-template",
734 | "version": "2.0.4",
735 | "source": {
736 | "type": "git",
737 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
738 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
739 | },
740 | "dist": {
741 | "type": "zip",
742 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
743 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
744 | "shasum": ""
745 | },
746 | "require": {
747 | "php": ">=7.3"
748 | },
749 | "require-dev": {
750 | "phpunit/phpunit": "^9.3"
751 | },
752 | "type": "library",
753 | "extra": {
754 | "branch-alias": {
755 | "dev-master": "2.0-dev"
756 | }
757 | },
758 | "autoload": {
759 | "classmap": [
760 | "src/"
761 | ]
762 | },
763 | "notification-url": "https://packagist.org/downloads/",
764 | "license": [
765 | "BSD-3-Clause"
766 | ],
767 | "authors": [
768 | {
769 | "name": "Sebastian Bergmann",
770 | "email": "sebastian@phpunit.de",
771 | "role": "lead"
772 | }
773 | ],
774 | "description": "Simple template engine.",
775 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
776 | "keywords": [
777 | "template"
778 | ],
779 | "support": {
780 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
781 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
782 | },
783 | "funding": [
784 | {
785 | "url": "https://github.com/sebastianbergmann",
786 | "type": "github"
787 | }
788 | ],
789 | "time": "2020-10-26T05:33:50+00:00"
790 | },
791 | {
792 | "name": "phpunit/php-timer",
793 | "version": "5.0.3",
794 | "source": {
795 | "type": "git",
796 | "url": "https://github.com/sebastianbergmann/php-timer.git",
797 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
798 | },
799 | "dist": {
800 | "type": "zip",
801 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
802 | "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
803 | "shasum": ""
804 | },
805 | "require": {
806 | "php": ">=7.3"
807 | },
808 | "require-dev": {
809 | "phpunit/phpunit": "^9.3"
810 | },
811 | "type": "library",
812 | "extra": {
813 | "branch-alias": {
814 | "dev-master": "5.0-dev"
815 | }
816 | },
817 | "autoload": {
818 | "classmap": [
819 | "src/"
820 | ]
821 | },
822 | "notification-url": "https://packagist.org/downloads/",
823 | "license": [
824 | "BSD-3-Clause"
825 | ],
826 | "authors": [
827 | {
828 | "name": "Sebastian Bergmann",
829 | "email": "sebastian@phpunit.de",
830 | "role": "lead"
831 | }
832 | ],
833 | "description": "Utility class for timing",
834 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
835 | "keywords": [
836 | "timer"
837 | ],
838 | "support": {
839 | "issues": "https://github.com/sebastianbergmann/php-timer/issues",
840 | "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
841 | },
842 | "funding": [
843 | {
844 | "url": "https://github.com/sebastianbergmann",
845 | "type": "github"
846 | }
847 | ],
848 | "time": "2020-10-26T13:16:10+00:00"
849 | },
850 | {
851 | "name": "phpunit/phpunit",
852 | "version": "9.5.21",
853 | "source": {
854 | "type": "git",
855 | "url": "https://github.com/sebastianbergmann/phpunit.git",
856 | "reference": "0e32b76be457de00e83213528f6bb37e2a38fcb1"
857 | },
858 | "dist": {
859 | "type": "zip",
860 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0e32b76be457de00e83213528f6bb37e2a38fcb1",
861 | "reference": "0e32b76be457de00e83213528f6bb37e2a38fcb1",
862 | "shasum": ""
863 | },
864 | "require": {
865 | "doctrine/instantiator": "^1.3.1",
866 | "ext-dom": "*",
867 | "ext-json": "*",
868 | "ext-libxml": "*",
869 | "ext-mbstring": "*",
870 | "ext-xml": "*",
871 | "ext-xmlwriter": "*",
872 | "myclabs/deep-copy": "^1.10.1",
873 | "phar-io/manifest": "^2.0.3",
874 | "phar-io/version": "^3.0.2",
875 | "php": ">=7.3",
876 | "phpspec/prophecy": "^1.12.1",
877 | "phpunit/php-code-coverage": "^9.2.13",
878 | "phpunit/php-file-iterator": "^3.0.5",
879 | "phpunit/php-invoker": "^3.1.1",
880 | "phpunit/php-text-template": "^2.0.3",
881 | "phpunit/php-timer": "^5.0.2",
882 | "sebastian/cli-parser": "^1.0.1",
883 | "sebastian/code-unit": "^1.0.6",
884 | "sebastian/comparator": "^4.0.5",
885 | "sebastian/diff": "^4.0.3",
886 | "sebastian/environment": "^5.1.3",
887 | "sebastian/exporter": "^4.0.3",
888 | "sebastian/global-state": "^5.0.1",
889 | "sebastian/object-enumerator": "^4.0.3",
890 | "sebastian/resource-operations": "^3.0.3",
891 | "sebastian/type": "^3.0",
892 | "sebastian/version": "^3.0.2"
893 | },
894 | "require-dev": {
895 | "phpspec/prophecy-phpunit": "^2.0.1"
896 | },
897 | "suggest": {
898 | "ext-soap": "*",
899 | "ext-xdebug": "*"
900 | },
901 | "bin": [
902 | "phpunit"
903 | ],
904 | "type": "library",
905 | "extra": {
906 | "branch-alias": {
907 | "dev-master": "9.5-dev"
908 | }
909 | },
910 | "autoload": {
911 | "files": [
912 | "src/Framework/Assert/Functions.php"
913 | ],
914 | "classmap": [
915 | "src/"
916 | ]
917 | },
918 | "notification-url": "https://packagist.org/downloads/",
919 | "license": [
920 | "BSD-3-Clause"
921 | ],
922 | "authors": [
923 | {
924 | "name": "Sebastian Bergmann",
925 | "email": "sebastian@phpunit.de",
926 | "role": "lead"
927 | }
928 | ],
929 | "description": "The PHP Unit Testing framework.",
930 | "homepage": "https://phpunit.de/",
931 | "keywords": [
932 | "phpunit",
933 | "testing",
934 | "xunit"
935 | ],
936 | "support": {
937 | "issues": "https://github.com/sebastianbergmann/phpunit/issues",
938 | "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.21"
939 | },
940 | "funding": [
941 | {
942 | "url": "https://phpunit.de/sponsors.html",
943 | "type": "custom"
944 | },
945 | {
946 | "url": "https://github.com/sebastianbergmann",
947 | "type": "github"
948 | }
949 | ],
950 | "time": "2022-06-19T12:14:25+00:00"
951 | },
952 | {
953 | "name": "sebastian/cli-parser",
954 | "version": "1.0.1",
955 | "source": {
956 | "type": "git",
957 | "url": "https://github.com/sebastianbergmann/cli-parser.git",
958 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
959 | },
960 | "dist": {
961 | "type": "zip",
962 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
963 | "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
964 | "shasum": ""
965 | },
966 | "require": {
967 | "php": ">=7.3"
968 | },
969 | "require-dev": {
970 | "phpunit/phpunit": "^9.3"
971 | },
972 | "type": "library",
973 | "extra": {
974 | "branch-alias": {
975 | "dev-master": "1.0-dev"
976 | }
977 | },
978 | "autoload": {
979 | "classmap": [
980 | "src/"
981 | ]
982 | },
983 | "notification-url": "https://packagist.org/downloads/",
984 | "license": [
985 | "BSD-3-Clause"
986 | ],
987 | "authors": [
988 | {
989 | "name": "Sebastian Bergmann",
990 | "email": "sebastian@phpunit.de",
991 | "role": "lead"
992 | }
993 | ],
994 | "description": "Library for parsing CLI options",
995 | "homepage": "https://github.com/sebastianbergmann/cli-parser",
996 | "support": {
997 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
998 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
999 | },
1000 | "funding": [
1001 | {
1002 | "url": "https://github.com/sebastianbergmann",
1003 | "type": "github"
1004 | }
1005 | ],
1006 | "time": "2020-09-28T06:08:49+00:00"
1007 | },
1008 | {
1009 | "name": "sebastian/code-unit",
1010 | "version": "1.0.8",
1011 | "source": {
1012 | "type": "git",
1013 | "url": "https://github.com/sebastianbergmann/code-unit.git",
1014 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
1015 | },
1016 | "dist": {
1017 | "type": "zip",
1018 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
1019 | "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
1020 | "shasum": ""
1021 | },
1022 | "require": {
1023 | "php": ">=7.3"
1024 | },
1025 | "require-dev": {
1026 | "phpunit/phpunit": "^9.3"
1027 | },
1028 | "type": "library",
1029 | "extra": {
1030 | "branch-alias": {
1031 | "dev-master": "1.0-dev"
1032 | }
1033 | },
1034 | "autoload": {
1035 | "classmap": [
1036 | "src/"
1037 | ]
1038 | },
1039 | "notification-url": "https://packagist.org/downloads/",
1040 | "license": [
1041 | "BSD-3-Clause"
1042 | ],
1043 | "authors": [
1044 | {
1045 | "name": "Sebastian Bergmann",
1046 | "email": "sebastian@phpunit.de",
1047 | "role": "lead"
1048 | }
1049 | ],
1050 | "description": "Collection of value objects that represent the PHP code units",
1051 | "homepage": "https://github.com/sebastianbergmann/code-unit",
1052 | "support": {
1053 | "issues": "https://github.com/sebastianbergmann/code-unit/issues",
1054 | "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
1055 | },
1056 | "funding": [
1057 | {
1058 | "url": "https://github.com/sebastianbergmann",
1059 | "type": "github"
1060 | }
1061 | ],
1062 | "time": "2020-10-26T13:08:54+00:00"
1063 | },
1064 | {
1065 | "name": "sebastian/code-unit-reverse-lookup",
1066 | "version": "2.0.3",
1067 | "source": {
1068 | "type": "git",
1069 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
1070 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
1071 | },
1072 | "dist": {
1073 | "type": "zip",
1074 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
1075 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
1076 | "shasum": ""
1077 | },
1078 | "require": {
1079 | "php": ">=7.3"
1080 | },
1081 | "require-dev": {
1082 | "phpunit/phpunit": "^9.3"
1083 | },
1084 | "type": "library",
1085 | "extra": {
1086 | "branch-alias": {
1087 | "dev-master": "2.0-dev"
1088 | }
1089 | },
1090 | "autoload": {
1091 | "classmap": [
1092 | "src/"
1093 | ]
1094 | },
1095 | "notification-url": "https://packagist.org/downloads/",
1096 | "license": [
1097 | "BSD-3-Clause"
1098 | ],
1099 | "authors": [
1100 | {
1101 | "name": "Sebastian Bergmann",
1102 | "email": "sebastian@phpunit.de"
1103 | }
1104 | ],
1105 | "description": "Looks up which function or method a line of code belongs to",
1106 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
1107 | "support": {
1108 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
1109 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3"
1110 | },
1111 | "funding": [
1112 | {
1113 | "url": "https://github.com/sebastianbergmann",
1114 | "type": "github"
1115 | }
1116 | ],
1117 | "time": "2020-09-28T05:30:19+00:00"
1118 | },
1119 | {
1120 | "name": "sebastian/comparator",
1121 | "version": "4.0.6",
1122 | "source": {
1123 | "type": "git",
1124 | "url": "https://github.com/sebastianbergmann/comparator.git",
1125 | "reference": "55f4261989e546dc112258c7a75935a81a7ce382"
1126 | },
1127 | "dist": {
1128 | "type": "zip",
1129 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382",
1130 | "reference": "55f4261989e546dc112258c7a75935a81a7ce382",
1131 | "shasum": ""
1132 | },
1133 | "require": {
1134 | "php": ">=7.3",
1135 | "sebastian/diff": "^4.0",
1136 | "sebastian/exporter": "^4.0"
1137 | },
1138 | "require-dev": {
1139 | "phpunit/phpunit": "^9.3"
1140 | },
1141 | "type": "library",
1142 | "extra": {
1143 | "branch-alias": {
1144 | "dev-master": "4.0-dev"
1145 | }
1146 | },
1147 | "autoload": {
1148 | "classmap": [
1149 | "src/"
1150 | ]
1151 | },
1152 | "notification-url": "https://packagist.org/downloads/",
1153 | "license": [
1154 | "BSD-3-Clause"
1155 | ],
1156 | "authors": [
1157 | {
1158 | "name": "Sebastian Bergmann",
1159 | "email": "sebastian@phpunit.de"
1160 | },
1161 | {
1162 | "name": "Jeff Welch",
1163 | "email": "whatthejeff@gmail.com"
1164 | },
1165 | {
1166 | "name": "Volker Dusch",
1167 | "email": "github@wallbash.com"
1168 | },
1169 | {
1170 | "name": "Bernhard Schussek",
1171 | "email": "bschussek@2bepublished.at"
1172 | }
1173 | ],
1174 | "description": "Provides the functionality to compare PHP values for equality",
1175 | "homepage": "https://github.com/sebastianbergmann/comparator",
1176 | "keywords": [
1177 | "comparator",
1178 | "compare",
1179 | "equality"
1180 | ],
1181 | "support": {
1182 | "issues": "https://github.com/sebastianbergmann/comparator/issues",
1183 | "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6"
1184 | },
1185 | "funding": [
1186 | {
1187 | "url": "https://github.com/sebastianbergmann",
1188 | "type": "github"
1189 | }
1190 | ],
1191 | "time": "2020-10-26T15:49:45+00:00"
1192 | },
1193 | {
1194 | "name": "sebastian/complexity",
1195 | "version": "2.0.2",
1196 | "source": {
1197 | "type": "git",
1198 | "url": "https://github.com/sebastianbergmann/complexity.git",
1199 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
1200 | },
1201 | "dist": {
1202 | "type": "zip",
1203 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
1204 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
1205 | "shasum": ""
1206 | },
1207 | "require": {
1208 | "nikic/php-parser": "^4.7",
1209 | "php": ">=7.3"
1210 | },
1211 | "require-dev": {
1212 | "phpunit/phpunit": "^9.3"
1213 | },
1214 | "type": "library",
1215 | "extra": {
1216 | "branch-alias": {
1217 | "dev-master": "2.0-dev"
1218 | }
1219 | },
1220 | "autoload": {
1221 | "classmap": [
1222 | "src/"
1223 | ]
1224 | },
1225 | "notification-url": "https://packagist.org/downloads/",
1226 | "license": [
1227 | "BSD-3-Clause"
1228 | ],
1229 | "authors": [
1230 | {
1231 | "name": "Sebastian Bergmann",
1232 | "email": "sebastian@phpunit.de",
1233 | "role": "lead"
1234 | }
1235 | ],
1236 | "description": "Library for calculating the complexity of PHP code units",
1237 | "homepage": "https://github.com/sebastianbergmann/complexity",
1238 | "support": {
1239 | "issues": "https://github.com/sebastianbergmann/complexity/issues",
1240 | "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
1241 | },
1242 | "funding": [
1243 | {
1244 | "url": "https://github.com/sebastianbergmann",
1245 | "type": "github"
1246 | }
1247 | ],
1248 | "time": "2020-10-26T15:52:27+00:00"
1249 | },
1250 | {
1251 | "name": "sebastian/diff",
1252 | "version": "4.0.4",
1253 | "source": {
1254 | "type": "git",
1255 | "url": "https://github.com/sebastianbergmann/diff.git",
1256 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d"
1257 | },
1258 | "dist": {
1259 | "type": "zip",
1260 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d",
1261 | "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d",
1262 | "shasum": ""
1263 | },
1264 | "require": {
1265 | "php": ">=7.3"
1266 | },
1267 | "require-dev": {
1268 | "phpunit/phpunit": "^9.3",
1269 | "symfony/process": "^4.2 || ^5"
1270 | },
1271 | "type": "library",
1272 | "extra": {
1273 | "branch-alias": {
1274 | "dev-master": "4.0-dev"
1275 | }
1276 | },
1277 | "autoload": {
1278 | "classmap": [
1279 | "src/"
1280 | ]
1281 | },
1282 | "notification-url": "https://packagist.org/downloads/",
1283 | "license": [
1284 | "BSD-3-Clause"
1285 | ],
1286 | "authors": [
1287 | {
1288 | "name": "Sebastian Bergmann",
1289 | "email": "sebastian@phpunit.de"
1290 | },
1291 | {
1292 | "name": "Kore Nordmann",
1293 | "email": "mail@kore-nordmann.de"
1294 | }
1295 | ],
1296 | "description": "Diff implementation",
1297 | "homepage": "https://github.com/sebastianbergmann/diff",
1298 | "keywords": [
1299 | "diff",
1300 | "udiff",
1301 | "unidiff",
1302 | "unified diff"
1303 | ],
1304 | "support": {
1305 | "issues": "https://github.com/sebastianbergmann/diff/issues",
1306 | "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
1307 | },
1308 | "funding": [
1309 | {
1310 | "url": "https://github.com/sebastianbergmann",
1311 | "type": "github"
1312 | }
1313 | ],
1314 | "time": "2020-10-26T13:10:38+00:00"
1315 | },
1316 | {
1317 | "name": "sebastian/environment",
1318 | "version": "5.1.4",
1319 | "source": {
1320 | "type": "git",
1321 | "url": "https://github.com/sebastianbergmann/environment.git",
1322 | "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7"
1323 | },
1324 | "dist": {
1325 | "type": "zip",
1326 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7",
1327 | "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7",
1328 | "shasum": ""
1329 | },
1330 | "require": {
1331 | "php": ">=7.3"
1332 | },
1333 | "require-dev": {
1334 | "phpunit/phpunit": "^9.3"
1335 | },
1336 | "suggest": {
1337 | "ext-posix": "*"
1338 | },
1339 | "type": "library",
1340 | "extra": {
1341 | "branch-alias": {
1342 | "dev-master": "5.1-dev"
1343 | }
1344 | },
1345 | "autoload": {
1346 | "classmap": [
1347 | "src/"
1348 | ]
1349 | },
1350 | "notification-url": "https://packagist.org/downloads/",
1351 | "license": [
1352 | "BSD-3-Clause"
1353 | ],
1354 | "authors": [
1355 | {
1356 | "name": "Sebastian Bergmann",
1357 | "email": "sebastian@phpunit.de"
1358 | }
1359 | ],
1360 | "description": "Provides functionality to handle HHVM/PHP environments",
1361 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1362 | "keywords": [
1363 | "Xdebug",
1364 | "environment",
1365 | "hhvm"
1366 | ],
1367 | "support": {
1368 | "issues": "https://github.com/sebastianbergmann/environment/issues",
1369 | "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4"
1370 | },
1371 | "funding": [
1372 | {
1373 | "url": "https://github.com/sebastianbergmann",
1374 | "type": "github"
1375 | }
1376 | ],
1377 | "time": "2022-04-03T09:37:03+00:00"
1378 | },
1379 | {
1380 | "name": "sebastian/exporter",
1381 | "version": "4.0.4",
1382 | "source": {
1383 | "type": "git",
1384 | "url": "https://github.com/sebastianbergmann/exporter.git",
1385 | "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9"
1386 | },
1387 | "dist": {
1388 | "type": "zip",
1389 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9",
1390 | "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9",
1391 | "shasum": ""
1392 | },
1393 | "require": {
1394 | "php": ">=7.3",
1395 | "sebastian/recursion-context": "^4.0"
1396 | },
1397 | "require-dev": {
1398 | "ext-mbstring": "*",
1399 | "phpunit/phpunit": "^9.3"
1400 | },
1401 | "type": "library",
1402 | "extra": {
1403 | "branch-alias": {
1404 | "dev-master": "4.0-dev"
1405 | }
1406 | },
1407 | "autoload": {
1408 | "classmap": [
1409 | "src/"
1410 | ]
1411 | },
1412 | "notification-url": "https://packagist.org/downloads/",
1413 | "license": [
1414 | "BSD-3-Clause"
1415 | ],
1416 | "authors": [
1417 | {
1418 | "name": "Sebastian Bergmann",
1419 | "email": "sebastian@phpunit.de"
1420 | },
1421 | {
1422 | "name": "Jeff Welch",
1423 | "email": "whatthejeff@gmail.com"
1424 | },
1425 | {
1426 | "name": "Volker Dusch",
1427 | "email": "github@wallbash.com"
1428 | },
1429 | {
1430 | "name": "Adam Harvey",
1431 | "email": "aharvey@php.net"
1432 | },
1433 | {
1434 | "name": "Bernhard Schussek",
1435 | "email": "bschussek@gmail.com"
1436 | }
1437 | ],
1438 | "description": "Provides the functionality to export PHP variables for visualization",
1439 | "homepage": "https://www.github.com/sebastianbergmann/exporter",
1440 | "keywords": [
1441 | "export",
1442 | "exporter"
1443 | ],
1444 | "support": {
1445 | "issues": "https://github.com/sebastianbergmann/exporter/issues",
1446 | "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4"
1447 | },
1448 | "funding": [
1449 | {
1450 | "url": "https://github.com/sebastianbergmann",
1451 | "type": "github"
1452 | }
1453 | ],
1454 | "time": "2021-11-11T14:18:36+00:00"
1455 | },
1456 | {
1457 | "name": "sebastian/global-state",
1458 | "version": "5.0.5",
1459 | "source": {
1460 | "type": "git",
1461 | "url": "https://github.com/sebastianbergmann/global-state.git",
1462 | "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2"
1463 | },
1464 | "dist": {
1465 | "type": "zip",
1466 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2",
1467 | "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2",
1468 | "shasum": ""
1469 | },
1470 | "require": {
1471 | "php": ">=7.3",
1472 | "sebastian/object-reflector": "^2.0",
1473 | "sebastian/recursion-context": "^4.0"
1474 | },
1475 | "require-dev": {
1476 | "ext-dom": "*",
1477 | "phpunit/phpunit": "^9.3"
1478 | },
1479 | "suggest": {
1480 | "ext-uopz": "*"
1481 | },
1482 | "type": "library",
1483 | "extra": {
1484 | "branch-alias": {
1485 | "dev-master": "5.0-dev"
1486 | }
1487 | },
1488 | "autoload": {
1489 | "classmap": [
1490 | "src/"
1491 | ]
1492 | },
1493 | "notification-url": "https://packagist.org/downloads/",
1494 | "license": [
1495 | "BSD-3-Clause"
1496 | ],
1497 | "authors": [
1498 | {
1499 | "name": "Sebastian Bergmann",
1500 | "email": "sebastian@phpunit.de"
1501 | }
1502 | ],
1503 | "description": "Snapshotting of global state",
1504 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1505 | "keywords": [
1506 | "global state"
1507 | ],
1508 | "support": {
1509 | "issues": "https://github.com/sebastianbergmann/global-state/issues",
1510 | "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5"
1511 | },
1512 | "funding": [
1513 | {
1514 | "url": "https://github.com/sebastianbergmann",
1515 | "type": "github"
1516 | }
1517 | ],
1518 | "time": "2022-02-14T08:28:10+00:00"
1519 | },
1520 | {
1521 | "name": "sebastian/lines-of-code",
1522 | "version": "1.0.3",
1523 | "source": {
1524 | "type": "git",
1525 | "url": "https://github.com/sebastianbergmann/lines-of-code.git",
1526 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
1527 | },
1528 | "dist": {
1529 | "type": "zip",
1530 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
1531 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
1532 | "shasum": ""
1533 | },
1534 | "require": {
1535 | "nikic/php-parser": "^4.6",
1536 | "php": ">=7.3"
1537 | },
1538 | "require-dev": {
1539 | "phpunit/phpunit": "^9.3"
1540 | },
1541 | "type": "library",
1542 | "extra": {
1543 | "branch-alias": {
1544 | "dev-master": "1.0-dev"
1545 | }
1546 | },
1547 | "autoload": {
1548 | "classmap": [
1549 | "src/"
1550 | ]
1551 | },
1552 | "notification-url": "https://packagist.org/downloads/",
1553 | "license": [
1554 | "BSD-3-Clause"
1555 | ],
1556 | "authors": [
1557 | {
1558 | "name": "Sebastian Bergmann",
1559 | "email": "sebastian@phpunit.de",
1560 | "role": "lead"
1561 | }
1562 | ],
1563 | "description": "Library for counting the lines of code in PHP source code",
1564 | "homepage": "https://github.com/sebastianbergmann/lines-of-code",
1565 | "support": {
1566 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
1567 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
1568 | },
1569 | "funding": [
1570 | {
1571 | "url": "https://github.com/sebastianbergmann",
1572 | "type": "github"
1573 | }
1574 | ],
1575 | "time": "2020-11-28T06:42:11+00:00"
1576 | },
1577 | {
1578 | "name": "sebastian/object-enumerator",
1579 | "version": "4.0.4",
1580 | "source": {
1581 | "type": "git",
1582 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1583 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
1584 | },
1585 | "dist": {
1586 | "type": "zip",
1587 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
1588 | "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
1589 | "shasum": ""
1590 | },
1591 | "require": {
1592 | "php": ">=7.3",
1593 | "sebastian/object-reflector": "^2.0",
1594 | "sebastian/recursion-context": "^4.0"
1595 | },
1596 | "require-dev": {
1597 | "phpunit/phpunit": "^9.3"
1598 | },
1599 | "type": "library",
1600 | "extra": {
1601 | "branch-alias": {
1602 | "dev-master": "4.0-dev"
1603 | }
1604 | },
1605 | "autoload": {
1606 | "classmap": [
1607 | "src/"
1608 | ]
1609 | },
1610 | "notification-url": "https://packagist.org/downloads/",
1611 | "license": [
1612 | "BSD-3-Clause"
1613 | ],
1614 | "authors": [
1615 | {
1616 | "name": "Sebastian Bergmann",
1617 | "email": "sebastian@phpunit.de"
1618 | }
1619 | ],
1620 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1621 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1622 | "support": {
1623 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
1624 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
1625 | },
1626 | "funding": [
1627 | {
1628 | "url": "https://github.com/sebastianbergmann",
1629 | "type": "github"
1630 | }
1631 | ],
1632 | "time": "2020-10-26T13:12:34+00:00"
1633 | },
1634 | {
1635 | "name": "sebastian/object-reflector",
1636 | "version": "2.0.4",
1637 | "source": {
1638 | "type": "git",
1639 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
1640 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
1641 | },
1642 | "dist": {
1643 | "type": "zip",
1644 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
1645 | "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
1646 | "shasum": ""
1647 | },
1648 | "require": {
1649 | "php": ">=7.3"
1650 | },
1651 | "require-dev": {
1652 | "phpunit/phpunit": "^9.3"
1653 | },
1654 | "type": "library",
1655 | "extra": {
1656 | "branch-alias": {
1657 | "dev-master": "2.0-dev"
1658 | }
1659 | },
1660 | "autoload": {
1661 | "classmap": [
1662 | "src/"
1663 | ]
1664 | },
1665 | "notification-url": "https://packagist.org/downloads/",
1666 | "license": [
1667 | "BSD-3-Clause"
1668 | ],
1669 | "authors": [
1670 | {
1671 | "name": "Sebastian Bergmann",
1672 | "email": "sebastian@phpunit.de"
1673 | }
1674 | ],
1675 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
1676 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
1677 | "support": {
1678 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
1679 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
1680 | },
1681 | "funding": [
1682 | {
1683 | "url": "https://github.com/sebastianbergmann",
1684 | "type": "github"
1685 | }
1686 | ],
1687 | "time": "2020-10-26T13:14:26+00:00"
1688 | },
1689 | {
1690 | "name": "sebastian/recursion-context",
1691 | "version": "4.0.4",
1692 | "source": {
1693 | "type": "git",
1694 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1695 | "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172"
1696 | },
1697 | "dist": {
1698 | "type": "zip",
1699 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172",
1700 | "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172",
1701 | "shasum": ""
1702 | },
1703 | "require": {
1704 | "php": ">=7.3"
1705 | },
1706 | "require-dev": {
1707 | "phpunit/phpunit": "^9.3"
1708 | },
1709 | "type": "library",
1710 | "extra": {
1711 | "branch-alias": {
1712 | "dev-master": "4.0-dev"
1713 | }
1714 | },
1715 | "autoload": {
1716 | "classmap": [
1717 | "src/"
1718 | ]
1719 | },
1720 | "notification-url": "https://packagist.org/downloads/",
1721 | "license": [
1722 | "BSD-3-Clause"
1723 | ],
1724 | "authors": [
1725 | {
1726 | "name": "Sebastian Bergmann",
1727 | "email": "sebastian@phpunit.de"
1728 | },
1729 | {
1730 | "name": "Jeff Welch",
1731 | "email": "whatthejeff@gmail.com"
1732 | },
1733 | {
1734 | "name": "Adam Harvey",
1735 | "email": "aharvey@php.net"
1736 | }
1737 | ],
1738 | "description": "Provides functionality to recursively process PHP variables",
1739 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1740 | "support": {
1741 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
1742 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4"
1743 | },
1744 | "funding": [
1745 | {
1746 | "url": "https://github.com/sebastianbergmann",
1747 | "type": "github"
1748 | }
1749 | ],
1750 | "time": "2020-10-26T13:17:30+00:00"
1751 | },
1752 | {
1753 | "name": "sebastian/resource-operations",
1754 | "version": "3.0.3",
1755 | "source": {
1756 | "type": "git",
1757 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
1758 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
1759 | },
1760 | "dist": {
1761 | "type": "zip",
1762 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
1763 | "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
1764 | "shasum": ""
1765 | },
1766 | "require": {
1767 | "php": ">=7.3"
1768 | },
1769 | "require-dev": {
1770 | "phpunit/phpunit": "^9.0"
1771 | },
1772 | "type": "library",
1773 | "extra": {
1774 | "branch-alias": {
1775 | "dev-master": "3.0-dev"
1776 | }
1777 | },
1778 | "autoload": {
1779 | "classmap": [
1780 | "src/"
1781 | ]
1782 | },
1783 | "notification-url": "https://packagist.org/downloads/",
1784 | "license": [
1785 | "BSD-3-Clause"
1786 | ],
1787 | "authors": [
1788 | {
1789 | "name": "Sebastian Bergmann",
1790 | "email": "sebastian@phpunit.de"
1791 | }
1792 | ],
1793 | "description": "Provides a list of PHP built-in functions that operate on resources",
1794 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
1795 | "support": {
1796 | "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
1797 | "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
1798 | },
1799 | "funding": [
1800 | {
1801 | "url": "https://github.com/sebastianbergmann",
1802 | "type": "github"
1803 | }
1804 | ],
1805 | "time": "2020-09-28T06:45:17+00:00"
1806 | },
1807 | {
1808 | "name": "sebastian/type",
1809 | "version": "3.0.0",
1810 | "source": {
1811 | "type": "git",
1812 | "url": "https://github.com/sebastianbergmann/type.git",
1813 | "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad"
1814 | },
1815 | "dist": {
1816 | "type": "zip",
1817 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
1818 | "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
1819 | "shasum": ""
1820 | },
1821 | "require": {
1822 | "php": ">=7.3"
1823 | },
1824 | "require-dev": {
1825 | "phpunit/phpunit": "^9.5"
1826 | },
1827 | "type": "library",
1828 | "extra": {
1829 | "branch-alias": {
1830 | "dev-master": "3.0-dev"
1831 | }
1832 | },
1833 | "autoload": {
1834 | "classmap": [
1835 | "src/"
1836 | ]
1837 | },
1838 | "notification-url": "https://packagist.org/downloads/",
1839 | "license": [
1840 | "BSD-3-Clause"
1841 | ],
1842 | "authors": [
1843 | {
1844 | "name": "Sebastian Bergmann",
1845 | "email": "sebastian@phpunit.de",
1846 | "role": "lead"
1847 | }
1848 | ],
1849 | "description": "Collection of value objects that represent the types of the PHP type system",
1850 | "homepage": "https://github.com/sebastianbergmann/type",
1851 | "support": {
1852 | "issues": "https://github.com/sebastianbergmann/type/issues",
1853 | "source": "https://github.com/sebastianbergmann/type/tree/3.0.0"
1854 | },
1855 | "funding": [
1856 | {
1857 | "url": "https://github.com/sebastianbergmann",
1858 | "type": "github"
1859 | }
1860 | ],
1861 | "time": "2022-03-15T09:54:48+00:00"
1862 | },
1863 | {
1864 | "name": "sebastian/version",
1865 | "version": "3.0.2",
1866 | "source": {
1867 | "type": "git",
1868 | "url": "https://github.com/sebastianbergmann/version.git",
1869 | "reference": "c6c1022351a901512170118436c764e473f6de8c"
1870 | },
1871 | "dist": {
1872 | "type": "zip",
1873 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
1874 | "reference": "c6c1022351a901512170118436c764e473f6de8c",
1875 | "shasum": ""
1876 | },
1877 | "require": {
1878 | "php": ">=7.3"
1879 | },
1880 | "type": "library",
1881 | "extra": {
1882 | "branch-alias": {
1883 | "dev-master": "3.0-dev"
1884 | }
1885 | },
1886 | "autoload": {
1887 | "classmap": [
1888 | "src/"
1889 | ]
1890 | },
1891 | "notification-url": "https://packagist.org/downloads/",
1892 | "license": [
1893 | "BSD-3-Clause"
1894 | ],
1895 | "authors": [
1896 | {
1897 | "name": "Sebastian Bergmann",
1898 | "email": "sebastian@phpunit.de",
1899 | "role": "lead"
1900 | }
1901 | ],
1902 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1903 | "homepage": "https://github.com/sebastianbergmann/version",
1904 | "support": {
1905 | "issues": "https://github.com/sebastianbergmann/version/issues",
1906 | "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
1907 | },
1908 | "funding": [
1909 | {
1910 | "url": "https://github.com/sebastianbergmann",
1911 | "type": "github"
1912 | }
1913 | ],
1914 | "time": "2020-09-28T06:39:44+00:00"
1915 | },
1916 | {
1917 | "name": "theseer/tokenizer",
1918 | "version": "1.2.1",
1919 | "source": {
1920 | "type": "git",
1921 | "url": "https://github.com/theseer/tokenizer.git",
1922 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
1923 | },
1924 | "dist": {
1925 | "type": "zip",
1926 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
1927 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
1928 | "shasum": ""
1929 | },
1930 | "require": {
1931 | "ext-dom": "*",
1932 | "ext-tokenizer": "*",
1933 | "ext-xmlwriter": "*",
1934 | "php": "^7.2 || ^8.0"
1935 | },
1936 | "type": "library",
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": "Arne Blankerts",
1949 | "email": "arne@blankerts.de",
1950 | "role": "Developer"
1951 | }
1952 | ],
1953 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
1954 | "support": {
1955 | "issues": "https://github.com/theseer/tokenizer/issues",
1956 | "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
1957 | },
1958 | "funding": [
1959 | {
1960 | "url": "https://github.com/theseer",
1961 | "type": "github"
1962 | }
1963 | ],
1964 | "time": "2021-07-28T10:34:58+00:00"
1965 | },
1966 | {
1967 | "name": "webmozart/assert",
1968 | "version": "1.11.0",
1969 | "source": {
1970 | "type": "git",
1971 | "url": "https://github.com/webmozarts/assert.git",
1972 | "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
1973 | },
1974 | "dist": {
1975 | "type": "zip",
1976 | "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
1977 | "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
1978 | "shasum": ""
1979 | },
1980 | "require": {
1981 | "ext-ctype": "*",
1982 | "php": "^7.2 || ^8.0"
1983 | },
1984 | "conflict": {
1985 | "phpstan/phpstan": "<0.12.20",
1986 | "vimeo/psalm": "<4.6.1 || 4.6.2"
1987 | },
1988 | "require-dev": {
1989 | "phpunit/phpunit": "^8.5.13"
1990 | },
1991 | "type": "library",
1992 | "extra": {
1993 | "branch-alias": {
1994 | "dev-master": "1.10-dev"
1995 | }
1996 | },
1997 | "autoload": {
1998 | "psr-4": {
1999 | "Webmozart\\Assert\\": "src/"
2000 | }
2001 | },
2002 | "notification-url": "https://packagist.org/downloads/",
2003 | "license": [
2004 | "MIT"
2005 | ],
2006 | "authors": [
2007 | {
2008 | "name": "Bernhard Schussek",
2009 | "email": "bschussek@gmail.com"
2010 | }
2011 | ],
2012 | "description": "Assertions to validate method input/output with nice error messages.",
2013 | "keywords": [
2014 | "assert",
2015 | "check",
2016 | "validate"
2017 | ],
2018 | "support": {
2019 | "issues": "https://github.com/webmozarts/assert/issues",
2020 | "source": "https://github.com/webmozarts/assert/tree/1.11.0"
2021 | },
2022 | "time": "2022-06-03T18:03:27+00:00"
2023 | }
2024 | ],
2025 | "packages-dev": [],
2026 | "aliases": [],
2027 | "minimum-stability": "stable",
2028 | "stability-flags": [],
2029 | "prefer-stable": false,
2030 | "prefer-lowest": false,
2031 | "platform": [],
2032 | "platform-dev": [],
2033 | "plugin-api-version": "2.3.0"
2034 | }
2035 |
--------------------------------------------------------------------------------
/ch12/design-patterns/src/DependencyInjection/ConstructorInjection.php:
--------------------------------------------------------------------------------
1 | logger = $logger;
14 | }
15 |
16 | public function doSomething(): void
17 | {
18 | // Some action happens here
19 |
20 | // Let us log something
21 | $this->logger->log('Some action has been done');
22 | }
23 | }
24 |
25 | $constructorInjection = new ConstructorInjection(
26 | new FileLogger()
27 | );
--------------------------------------------------------------------------------
/ch12/design-patterns/src/DependencyInjection/FileLogger.php:
--------------------------------------------------------------------------------
1 | logger = new FileLogger();
14 | }
15 |
16 | public function doSomething(): void
17 | {
18 | // Some action happens here
19 |
20 | // Let us log something
21 | $this->logger->log('Some action has been done');
22 | }
23 | }
--------------------------------------------------------------------------------
/ch12/design-patterns/src/DependencyInjection/Logger.php:
--------------------------------------------------------------------------------
1 | logger = $logger;
18 | }
19 |
20 | public function doSomething(): void
21 | {
22 | // Some action happens here
23 |
24 | // Let us log something
25 | $this->logger->log('Some action has been done');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ch12/design-patterns/src/DependencyInjection/SetterInjectionFactory.php:
--------------------------------------------------------------------------------
1 | setLogger(new FileLogger());
13 |
14 | return $setterInjection;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch12/design-patterns/src/FactoryMethod/AbstractWriter.php:
--------------------------------------------------------------------------------
1 | createEncoder();
12 |
13 | // Apply some filtering which should always happen,
14 | // regardless of the output format.
15 | array_walk(
16 | $data,
17 | function (&$value) {
18 | $value = str_replace('data', '', $value);
19 | }
20 | );
21 |
22 | // For demonstration purposes, we echo the result
23 | // here, instead of writing it into a file
24 | echo $encoder->encode($data);
25 | }
26 |
27 | abstract protected function createEncoder(): Encoder;
28 | }
--------------------------------------------------------------------------------
/ch12/design-patterns/src/FactoryMethod/CsvEncoder.php:
--------------------------------------------------------------------------------
1 | write($exampleData);
17 |
18 | echo PHP_EOL;
19 | }
20 |
21 | echo "Output using the CsvWriter:" . PHP_EOL;
22 |
23 | factoryMethodExample(new CsvWriter());
24 |
25 | echo "Output using the JsonWriter:" . PHP_EOL;
26 |
27 | factoryMethodExample(new JsonWriter());
--------------------------------------------------------------------------------
/ch12/design-patterns/src/FactoryMethod/JsonEncoder.php:
--------------------------------------------------------------------------------
1 | observers = new SplObjectStorage();
20 | }
21 |
22 | public function attach(SplObserver $observer): void
23 | {
24 | $this->observers->attach($observer);
25 | }
26 |
27 | public function detach(SplObserver $observer): void
28 | {
29 | $this->observers->detach($observer);
30 | }
31 |
32 | public function notify(): void
33 | {
34 | foreach ($this->observers as $observer) {
35 | $observer->update($this);
36 | }
37 | }
38 |
39 | public function cancelSubscription(): void
40 | {
41 | // Required code for the actual cancellation
42 | // ...
43 |
44 | $this->notify();
45 | }
46 | }
--------------------------------------------------------------------------------
/ch12/design-patterns/src/Obvserver/CustomerAccountObserver.php:
--------------------------------------------------------------------------------
1 | mailService->sendEmail(
19 | 'sales@example.com',
20 | 'Account ' . $splSubject->id . ' has cancelled the subscription'
21 | );
22 | }
23 | }
--------------------------------------------------------------------------------
/ch12/design-patterns/src/Obvserver/MailService.php:
--------------------------------------------------------------------------------
1 | mailService->sendEmail(
21 | 'sales@example.com',
22 | 'Account ' . $this->id . ' has cancelled the subscription'
23 | );
24 | }
25 | }
--------------------------------------------------------------------------------
/ch12/design-patterns/src/Obvserver/bootstrap.php:
--------------------------------------------------------------------------------
1 | attach($customerAccountObserver);
--------------------------------------------------------------------------------
/ch12/design-patterns/src/ServiceLocator/ServiceLocator.php:
--------------------------------------------------------------------------------
1 | serviceLocator->get(SomeService::class);
16 | $someService->doSomething();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch12/design-patterns/src/ServiceLocator/SomeService.php:
--------------------------------------------------------------------------------
1 | to write great PHP code?} --> B[No]
9 | A --> C[Yes]
10 | C --> E(Awesome!)
11 | B --> D{Did you read
Clean Code in PHP?} --> F[No]
12 | D --> G[Yes]
13 | G --> H(Please read it again)
14 | F --> I(Please read it)
15 | ```
--------------------------------------------------------------------------------
/ch13/openapi/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 | composer.lock
--------------------------------------------------------------------------------
/ch13/openapi/README.md:
--------------------------------------------------------------------------------
1 | # OpenAPI example
2 |
3 | ## Installation
4 |
5 | Run `composer install`
6 |
7 | ## Create the API documentation
8 |
9 | 1. `vendor/bin/openapi src/Annotations -o openapi-annotations.yaml` to create the documentation using the Annotations example
10 | 2. `vendor/bin/openapi src/Attributes -o openapi-attributes.yaml` to create the documentation using the Attributes example
11 |
12 | ## Compare both YAML files
13 |
14 | To check for differences between both YAML files, you can use `git diff --no-index to compare files which are not tracked by git:
15 |
16 | `git diff --no-index openapi-annotations.yaml openapi-attributes.yaml`
17 |
18 | If all went fine, you should not get any difference reported.
19 |
20 | ## Swagger UI
21 |
22 | As quick example, pull the Swagger-UI from Docker Hub:
23 |
24 | `docker pull swaggerapi/swagger-ui`
25 |
26 | Since Swagger-UI required a JSON instead a YAML, create one first:
27 |
28 | `vendor/bin/openapi src/Attributes -o openapi-attributes.json`
29 |
30 | Then, run the container locally:
31 |
32 | ```
33 | docker run -p 80:8080 -e SWAGGER_JSON=/foo/openapi-attributes.json -v `pwd`:/foo swaggerapi/swagger-ui
34 | ```
35 |
36 | Now you can open http://localhost in your browser.
--------------------------------------------------------------------------------
/ch13/openapi/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "autoload": {
3 | "psr-4": {
4 | "OpenApiExample\\":"src/"
5 | }
6 | },
7 | "require": {
8 | "zircote/swagger-php": "^4.4"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ch13/openapi/openapi-annotations.yaml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.0
2 | info:
3 | title: 'Product API'
4 | version: '0.1'
5 | paths:
6 | /product:
7 | get:
8 | operationId: getProducts
9 | parameters:
10 | -
11 | name: limit
12 | in: query
13 | description: 'How many products to return at one time'
14 | required: false
15 | schema:
16 | type: integer
17 | responses:
18 | '200':
19 | description: 'Returns the product data'
20 |
--------------------------------------------------------------------------------
/ch13/openapi/openapi-attributes.json:
--------------------------------------------------------------------------------
1 | {
2 | "openapi": "3.0.0",
3 | "info": {
4 | "title": "Product API",
5 | "version": "0.1"
6 | },
7 | "paths": {
8 | "/product": {
9 | "get": {
10 | "operationId": "getProducts",
11 | "parameters": [
12 | {
13 | "name": "limit",
14 | "in": "query",
15 | "description": "How many products to return at one time",
16 | "required": false,
17 | "schema": {
18 | "type": "integer"
19 | }
20 | }
21 | ],
22 | "responses": {
23 | "200": {
24 | "description": "Returns the product data"
25 | }
26 | }
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/ch13/openapi/openapi-attributes.yaml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.0
2 | info:
3 | title: 'Product API'
4 | version: '0.1'
5 | paths:
6 | /product:
7 | get:
8 | operationId: getProducts
9 | parameters:
10 | -
11 | name: limit
12 | in: query
13 | description: 'How many products to return at one time'
14 | required: false
15 | schema:
16 | type: integer
17 | responses:
18 | '200':
19 | description: 'Returns the product data'
20 |
--------------------------------------------------------------------------------
/ch13/openapi/src/Annotations/Controller/ProductController.php:
--------------------------------------------------------------------------------
1 |