From db215b0eb1990f34a9f092aeac12eff3eb3dc9fd Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Fri, 3 Nov 2023 18:14:40 +0100 Subject: [PATCH 01/20] refactor: Update package to support php >=8 and Psr Log 2 || 3 Updating dependencies to be able to work with newer Psr/Log BREAKING CHANGE: we are dropping support for PHP 7.x and Psr/Log 1.x --- composer.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 4a5c981..88d5db0 100644 --- a/composer.json +++ b/composer.json @@ -37,22 +37,22 @@ } ], "require": { - "php": ">=7.2 < 8.3", - "psr/log": "^1.1.4", + "php": ">=8.0", + "psr/log": "^2.0||^3.0", "wecodemore/wordpress-early-hook": "^1.1.0", "monolog/monolog": "^2.3.5" }, "require-dev": { - "phpunit/phpunit": "^8.5.33", "brain/monkey": "^2.6.1", "mockery/mockery": "^1.3.6", "mikey179/vfsstream": "~v1.6.11", "inpsyde/php-coding-standards": "^1", - "vimeo/psalm": "^4.30.0", "inpsyde/wp-stubs-versions": "dev-latest", "roots/wordpress-no-content": ">=6.1.1", "symfony/process": "^v4.4.44", - "globalis/wp-cli-bin": "^2.7.1" + "globalis/wp-cli-bin": "^2.7.1", + "vimeo/psalm": "^5.15", + "phpunit/phpunit": "^9.6" }, "provide": { "psr/log-implementation": "1.0.0" From 83e07a300749b74f164b010d89b059907f431f83 Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Fri, 3 Nov 2023 18:23:29 +0100 Subject: [PATCH 02/20] ci: remove php 7.x workflow run --- .github/workflows/php-integration-tests.yml | 2 +- .github/workflows/php-static-analysis.yml | 2 +- .github/workflows/php-unit-tests.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/php-integration-tests.yml b/.github/workflows/php-integration-tests.yml index 338cf1f..8bc1032 100644 --- a/.github/workflows/php-integration-tests.yml +++ b/.github/workflows/php-integration-tests.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - php-service: [ '72', '73', '74', '80', '81', '82' ] + php-service: [ '80', '81', '82' ] steps: - name: Checkout uses: actions/checkout@v3 diff --git a/.github/workflows/php-static-analysis.yml b/.github/workflows/php-static-analysis.yml index dedcd5b..1559e72 100644 --- a/.github/workflows/php-static-analysis.yml +++ b/.github/workflows/php-static-analysis.yml @@ -31,7 +31,7 @@ jobs: uses: inpsyde/reusable-workflows/.github/workflows/lint-php.yml@main if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run lint only')) }} with: - PHP_MATRIX: '["7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]' + PHP_MATRIX: '["8.0", "8.1", "8.2"]' coding-standards-analysis-php: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} diff --git a/.github/workflows/php-unit-tests.yml b/.github/workflows/php-unit-tests.yml index 1953aff..0da81ca 100644 --- a/.github/workflows/php-unit-tests.yml +++ b/.github/workflows/php-unit-tests.yml @@ -25,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2' ] + php-versions: [ '8.0', '8.1', '8.2' ] steps: - name: Checkout From 80d0da68e8b3a425b8a9951036cc62e10088f5de Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Fri, 3 Nov 2023 18:35:22 +0100 Subject: [PATCH 03/20] chore: add static analysis for php 8.0 8.1 8.2 --- .github/workflows/php-static-analysis.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/php-static-analysis.yml b/.github/workflows/php-static-analysis.yml index 1559e72..5b7dfde 100644 --- a/.github/workflows/php-static-analysis.yml +++ b/.github/workflows/php-static-analysis.yml @@ -33,9 +33,21 @@ jobs: with: PHP_MATRIX: '["8.0", "8.1", "8.2"]' - coding-standards-analysis-php: + coding-standards-analysis-php-80: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} uses: inpsyde/reusable-workflows/.github/workflows/coding-standards-php.yml@main + with: + PHP_VERSION: '8.0' + coding-standards-analysis-php-81: + if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} + uses: inpsyde/reusable-workflows/.github/workflows/coding-standards-php.yml@main + with: + PHP_VERSION: '8.1' + coding-standards-analysis-php-82: + if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} + uses: inpsyde/reusable-workflows/.github/workflows/coding-standards-php.yml@main + with: + PHP_VERSION: '8.2' static-code-analysis-php: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run Psalm only')) }} From 3c14a3f001056c54e9729e7a6cc85672d6b9bfd4 Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Fri, 3 Nov 2023 18:39:29 +0100 Subject: [PATCH 04/20] chore: add static code analysis for different php versions --- .github/workflows/php-static-analysis.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/php-static-analysis.yml b/.github/workflows/php-static-analysis.yml index 5b7dfde..c7facd3 100644 --- a/.github/workflows/php-static-analysis.yml +++ b/.github/workflows/php-static-analysis.yml @@ -49,6 +49,19 @@ jobs: with: PHP_VERSION: '8.2' - static-code-analysis-php: + static-code-analysis-php-80: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run Psalm only')) }} uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main + with: + PHP_VERSION: '8.0' + static-code-analysis-php-81: + if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run Psalm only')) }} + uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main + with: + PHP_VERSION: '8.1' + static-code-analysis-php-82: + if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run Psalm only')) }} + uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main + with: + PHP_VERSION: '8.2' + From 0c2fe9cc3fcf1b85b24aef00297a942528f67c0a Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Fri, 3 Nov 2023 19:14:47 +0100 Subject: [PATCH 05/20] chore: fixes psalm error Ignore error comming from the different return type on earlier versions of WP In WP < 6.1 the return type was array[]|false --- src/HookListener/CronDebugListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HookListener/CronDebugListener.php b/src/HookListener/CronDebugListener.php index 7e3d43c..1e17b78 100644 --- a/src/HookListener/CronDebugListener.php +++ b/src/HookListener/CronDebugListener.php @@ -83,7 +83,7 @@ private function registerEventListener(LogActionUpdater $updater): void } $cronArray = _get_cron_array(); - /** @psalm-suppress DocblockTypeContradiction */ + /** @psalm-suppress TypeDoesNotContainType,DocblockTypeContradiction */ if (!$cronArray || !is_array($cronArray)) { return; } From e9dfe4e1a60e1b47c9297063e2229b7e21650713 Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Mon, 6 Nov 2023 11:19:12 +0100 Subject: [PATCH 06/20] chore: fix psalm and require the test package --- .gitignore | 4 ++++ composer.json | 3 ++- src/Data/FailedLogin.php | 14 ++++++++++++-- src/DefaultHandler/LogsFolder.php | 4 ++++ src/PsrBridge.php | 2 +- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index a57a787..6a78a68 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,7 @@ # Docker .github/workflows/docker/php*/*.sh + +# Adding a folder to put things temporarily +temp/ + diff --git a/composer.json b/composer.json index 88d5db0..df2b4e3 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,8 @@ "symfony/process": "^v4.4.44", "globalis/wp-cli-bin": "^2.7.1", "vimeo/psalm": "^5.15", - "phpunit/phpunit": "^9.6" + "phpunit/phpunit": "^9.6", + "fig/log-test": "^1.1" }, "provide": { "psr/log-implementation": "1.0.0" diff --git a/src/Data/FailedLogin.php b/src/Data/FailedLogin.php index 8daec23..101b4e6 100644 --- a/src/Data/FailedLogin.php +++ b/src/Data/FailedLogin.php @@ -107,15 +107,25 @@ private function countAttempts(int $ttl = 300): void || !isset($attempts[$userIp]['count']) || !isset($attempts[$userIp]['last_logged']) ) { - $attempts[$userIp] = ['count' => 0, 'last_logged' => 0]; + /** + * @var array $data + */ + $data = ['count' => 0, 'last_logged' => 0]; + $attempts[$userIp] = $data; } /** @psalm-suppress MixedOperand */ $attempts[$userIp]['count']++; - /** @psalm-suppress PropertyTypeCoercion */ + /** @psalm-suppress InvalidPropertyAssignmentValue */ $this->attemptsData = $attempts; + /** + * Psalm warns us about count and last_logged possibly being bool to int converted + * We assume the value retrieved when calling get_site_transient is an integer on both + * @psalm-suppress RiskyCast + */ $count = (int)$attempts[$userIp]['count']; + /** @psalm-suppress RiskyCast */ $lastLogged = (int)$attempts[$userIp]['last_logged']; /** diff --git a/src/DefaultHandler/LogsFolder.php b/src/DefaultHandler/LogsFolder.php index ef4736b..7ab3ba4 100644 --- a/src/DefaultHandler/LogsFolder.php +++ b/src/DefaultHandler/LogsFolder.php @@ -35,7 +35,11 @@ public static function determineFolder(?string $customFolder = null): ?string * them, and package could be fully functional even if failures happen. * Silence looks like best option here. * + * Also for some reason __return_true seems not to be a valid argument¿? + * I found this related issue https://github.com/vimeo/psalm/issues/3571 + * * phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler + * @psalm-suppress PossiblyInvalidArgument */ set_error_handler('__return_true'); diff --git a/src/PsrBridge.php b/src/PsrBridge.php index d2eaf65..182a7fc 100644 --- a/src/PsrBridge.php +++ b/src/PsrBridge.php @@ -72,7 +72,7 @@ public function withDefaultChannel(string $defaultChannel): PsrBridge * * phpcs:disable Generic.Metrics.CyclomaticComplexity */ - public function log($level, $message, array $context = []) + public function log($level, $message, array $context = []): void { // phpcs:enable Generic.Metrics.CyclomaticComplexity $throwable = null; From 685d0d38e0ead8c89b8114c69cc68cb171a35ae2 Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Mon, 6 Nov 2023 11:31:06 +0100 Subject: [PATCH 07/20] chore: remove deprecation warning in tests --- tests/unit/HookListener/CronDebugListenerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/HookListener/CronDebugListenerTest.php b/tests/unit/HookListener/CronDebugListenerTest.php index ae5eebf..0df22a5 100644 --- a/tests/unit/HookListener/CronDebugListenerTest.php +++ b/tests/unit/HookListener/CronDebugListenerTest.php @@ -109,8 +109,8 @@ static function (LogData $log) use (&$logs): void { $regxp = '~^Cron action "%s" performed\. Duration: [0|1]\.[0-9]+ seconds\.$~'; - static::assertRegExp(sprintf($regxp, 'wp_scheduled_delete'), $logs[0]); - static::assertRegExp(sprintf($regxp, 'wp_update_plugins'), $logs[1]); - static::assertRegExp(sprintf($regxp, 'wp_version_check'), $logs[2]); + static::assertMatchesRegularExpression(sprintf($regxp, 'wp_scheduled_delete'), $logs[0]); + static::assertMatchesRegularExpression(sprintf($regxp, 'wp_update_plugins'), $logs[1]); + static::assertMatchesRegularExpression(sprintf($regxp, 'wp_version_check'), $logs[2]); } } From c3b39a28439b0a15b8500421c56e3af68ab228df Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Mon, 6 Nov 2023 11:46:52 +0100 Subject: [PATCH 08/20] chore: remove phpunit warning about config file using outdated schema --- phpunit.xml.dist | 60 ++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d2d7421..85875ac 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,34 +1,30 @@ - - - - - - - - - tests/unit - - - tests/integration - - - - - - src - - + + + + src + + + + + + + + tests/unit + + + tests/integration + + From 2c9d84edab88d044eb6b6c5c51360e66d95cb285 Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Mon, 6 Nov 2023 11:52:56 +0100 Subject: [PATCH 09/20] chore: increase the php unit test matrix to use prefer lowest and regular --- .github/workflows/php-unit-tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/php-unit-tests.yml b/.github/workflows/php-unit-tests.yml index 0da81ca..776b49c 100644 --- a/.github/workflows/php-unit-tests.yml +++ b/.github/workflows/php-unit-tests.yml @@ -26,6 +26,7 @@ jobs: fail-fast: false matrix: php-versions: [ '8.0', '8.1', '8.2' ] + dependency-versions: ['highest', 'lowest'] steps: - name: Checkout @@ -44,6 +45,8 @@ jobs: - name: Install Composer dependencies uses: ramsey/composer-install@v2 + with: + dependency-versions: ${{ matrix.dependency-versions }} - name: Run unit tests run: composer tests:unit:${{ ((env.USE_COVERAGE == 'yes') && 'codecov') || 'no-cov' }} From 9a2ad1c471bc8dd3045c089299fbbe1146915efc Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Wed, 8 Nov 2023 10:05:03 +0100 Subject: [PATCH 10/20] chore: using matrix instead --- .github/workflows/php-static-analysis.yml | 35 +++++++---------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/.github/workflows/php-static-analysis.yml b/.github/workflows/php-static-analysis.yml index c7facd3..58261ce 100644 --- a/.github/workflows/php-static-analysis.yml +++ b/.github/workflows/php-static-analysis.yml @@ -33,35 +33,20 @@ jobs: with: PHP_MATRIX: '["8.0", "8.1", "8.2"]' - coding-standards-analysis-php-80: + coding-standards-analysis-php: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} uses: inpsyde/reusable-workflows/.github/workflows/coding-standards-php.yml@main + strategy: + matrix: + php-version: ['8.0', '8.1', '8.2'] with: - PHP_VERSION: '8.0' - coding-standards-analysis-php-81: - if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} - uses: inpsyde/reusable-workflows/.github/workflows/coding-standards-php.yml@main - with: - PHP_VERSION: '8.1' - coding-standards-analysis-php-82: - if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} - uses: inpsyde/reusable-workflows/.github/workflows/coding-standards-php.yml@main - with: - PHP_VERSION: '8.2' + PHP_VERSION: ${{ matrix.php-version }} - static-code-analysis-php-80: + static-code-analysis-php: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run Psalm only')) }} uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main + strategy: + matrix: + php-version: [ '8.0', '8.1', '8.2' ] with: - PHP_VERSION: '8.0' - static-code-analysis-php-81: - if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run Psalm only')) }} - uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main - with: - PHP_VERSION: '8.1' - static-code-analysis-php-82: - if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run Psalm only')) }} - uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main - with: - PHP_VERSION: '8.2' - + PHP_VERSION: ${{ matrix.php-version }} From 1d5b573ade91c84c489405c8de0d15c426a6055c Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Wed, 8 Nov 2023 11:00:10 +0100 Subject: [PATCH 11/20] chore: be more specific in suportted php versions --- composer.json | 2 +- src/DefaultHandler/LogsFolder.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index df2b4e3..4befb5a 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ } ], "require": { - "php": ">=8.0", + "php": ">=8.0 < 8.3", "psr/log": "^2.0||^3.0", "wecodemore/wordpress-early-hook": "^1.1.0", "monolog/monolog": "^2.3.5" diff --git a/src/DefaultHandler/LogsFolder.php b/src/DefaultHandler/LogsFolder.php index 7ab3ba4..0954531 100644 --- a/src/DefaultHandler/LogsFolder.php +++ b/src/DefaultHandler/LogsFolder.php @@ -35,7 +35,7 @@ public static function determineFolder(?string $customFolder = null): ?string * them, and package could be fully functional even if failures happen. * Silence looks like best option here. * - * Also for some reason __return_true seems not to be a valid argument¿? + * Also for some reason __return_true seems not to be a valid argument? * I found this related issue https://github.com/vimeo/psalm/issues/3571 * * phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler From 6f2c987ddc11d1f576dd5496882423ffc441e51a Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Wed, 8 Nov 2023 14:43:33 +0100 Subject: [PATCH 12/20] chore: PHP CS will return same result for all versions --- .github/workflows/php-static-analysis.yml | 5 +---- .gitignore | 3 +++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/php-static-analysis.yml b/.github/workflows/php-static-analysis.yml index 58261ce..2f084cb 100644 --- a/.github/workflows/php-static-analysis.yml +++ b/.github/workflows/php-static-analysis.yml @@ -36,11 +36,8 @@ jobs: coding-standards-analysis-php: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} uses: inpsyde/reusable-workflows/.github/workflows/coding-standards-php.yml@main - strategy: - matrix: - php-version: ['8.0', '8.1', '8.2'] with: - PHP_VERSION: ${{ matrix.php-version }} + PHP_VERSION: '8.0' static-code-analysis-php: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run Psalm only')) }} diff --git a/.gitignore b/.gitignore index 6a78a68..6c97b07 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ # Adding a folder to put things temporarily temp/ +# IDE +.idea/ + From 163498ee7b7a56a87092cab5ac61e63149445935 Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Tue, 28 Nov 2023 18:49:04 +0100 Subject: [PATCH 13/20] feat: adds supports for 7.4 and compat with psr/log 1 --- .github/workflows/php-unit-tests.yml | 18 +- composer.json | 9 +- tests/src/TestLogger/AbstractLoggerV1.php | 139 +++++++++ tests/src/TestLogger/TestLoggerV1.php | 161 +++++++++++ tests/src/TestLogger/TestLoggerV2V3.php | 338 ++++++++++++++++++++++ tests/unit/LogActionUpdaterTest.php | 12 +- 6 files changed, 655 insertions(+), 22 deletions(-) create mode 100644 tests/src/TestLogger/AbstractLoggerV1.php create mode 100644 tests/src/TestLogger/TestLoggerV1.php create mode 100644 tests/src/TestLogger/TestLoggerV2V3.php diff --git a/.github/workflows/php-unit-tests.yml b/.github/workflows/php-unit-tests.yml index 776b49c..b3ad1a9 100644 --- a/.github/workflows/php-unit-tests.yml +++ b/.github/workflows/php-unit-tests.yml @@ -25,23 +25,19 @@ jobs: strategy: fail-fast: false matrix: - php-versions: [ '8.0', '8.1', '8.2' ] + php-versions: [ '7.4', '8.0', '8.1', '8.2' ] dependency-versions: ['highest', 'lowest'] steps: - name: Checkout uses: actions/checkout@v3 - - name: Use coverage? - if: ${{ matrix.php-versions == '7.4' }} - run: echo "USE_COVERAGE=yes" >> $GITHUB_ENV - - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} ini-values: zend.assertions=1, error_reporting=E_ALL, display_errors=On - coverage: ${{ ((env.USE_COVERAGE == 'yes') && 'xdebug') || 'none' }} + coverage: ${{ env.USE_COVERAGE == 'yes' && 'xdebug' || 'none' }} - name: Install Composer dependencies uses: ramsey/composer-install@v2 @@ -49,14 +45,6 @@ jobs: dependency-versions: ${{ matrix.dependency-versions }} - name: Run unit tests - run: composer tests:unit:${{ ((env.USE_COVERAGE == 'yes') && 'codecov') || 'no-cov' }} + run: composer tests:unit:no-cov - - name: Update coverage - if: ${{ env.USE_COVERAGE == 'yes' }} - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./coverage.xml - flags: unittests - verbose: true diff --git a/composer.json b/composer.json index 4befb5a..f37c383 100644 --- a/composer.json +++ b/composer.json @@ -37,10 +37,10 @@ } ], "require": { - "php": ">=8.0 < 8.3", - "psr/log": "^2.0||^3.0", + "php": "^7.4||>=8.0 < 8.3", + "psr/log": ">1.0.1 <2.0||^2.0||^3.0", "wecodemore/wordpress-early-hook": "^1.1.0", - "monolog/monolog": "^2.3.5" + "monolog/monolog": ">=2.0.1 <3" }, "require-dev": { "brain/monkey": "^2.6.1", @@ -52,8 +52,7 @@ "symfony/process": "^v4.4.44", "globalis/wp-cli-bin": "^2.7.1", "vimeo/psalm": "^5.15", - "phpunit/phpunit": "^9.6", - "fig/log-test": "^1.1" + "phpunit/phpunit": "^9.6" }, "provide": { "psr/log-implementation": "1.0.0" diff --git a/tests/src/TestLogger/AbstractLoggerV1.php b/tests/src/TestLogger/AbstractLoggerV1.php new file mode 100644 index 0000000..8a774b9 --- /dev/null +++ b/tests/src/TestLogger/AbstractLoggerV1.php @@ -0,0 +1,139 @@ + + * @license GPLv2+ + * @link https://www.inpsyde.com + */ + +namespace Inpsyde\Wonolog\Tests\TestLogger; + +use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; + +abstract class AbstractLoggerV1 implements LoggerInterface +{ + /** + * System is unusable. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function emergency($message, array $context = array()) + { + $this->log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +} \ No newline at end of file diff --git a/tests/src/TestLogger/TestLoggerV1.php b/tests/src/TestLogger/TestLoggerV1.php new file mode 100644 index 0000000..3006293 --- /dev/null +++ b/tests/src/TestLogger/TestLoggerV1.php @@ -0,0 +1,161 @@ + + * @license GPLv2+ + * @link https://www.inpsyde.com + */ + +namespace Inpsyde\Wonolog\Tests\TestLogger; + +/** + * Used for testing purposes. + * + * It records all records and gives you access to them for verification. + * + * @method bool hasEmergency($record) + * @method bool hasAlert($record) + * @method bool hasCritical($record) + * @method bool hasError($record) + * @method bool hasWarning($record) + * @method bool hasNotice($record) + * @method bool hasInfo($record) + * @method bool hasDebug($record) + * + * @method bool hasEmergencyRecords() + * @method bool hasAlertRecords() + * @method bool hasCriticalRecords() + * @method bool hasErrorRecords() + * @method bool hasWarningRecords() + * @method bool hasNoticeRecords() + * @method bool hasInfoRecords() + * @method bool hasDebugRecords() + * + * @method bool hasEmergencyThatContains($message) + * @method bool hasAlertThatContains($message) + * @method bool hasCriticalThatContains($message) + * @method bool hasErrorThatContains($message) + * @method bool hasWarningThatContains($message) + * @method bool hasNoticeThatContains($message) + * @method bool hasInfoThatContains($message) + * @method bool hasDebugThatContains($message) + * + * @method bool hasEmergencyThatMatches($message) + * @method bool hasAlertThatMatches($message) + * @method bool hasCriticalThatMatches($message) + * @method bool hasErrorThatMatches($message) + * @method bool hasWarningThatMatches($message) + * @method bool hasNoticeThatMatches($message) + * @method bool hasInfoThatMatches($message) + * @method bool hasDebugThatMatches($message) + * + * @method bool hasEmergencyThatPasses($message) + * @method bool hasAlertThatPasses($message) + * @method bool hasCriticalThatPasses($message) + * @method bool hasErrorThatPasses($message) + * @method bool hasWarningThatPasses($message) + * @method bool hasNoticeThatPasses($message) + * @method bool hasInfoThatPasses($message) + * @method bool hasDebugThatPasses($message) + */ +class TestLoggerV1 extends AbstractLoggerV1 +{ + /** + * @var array + */ + public $records = []; + + public $recordsByLevel = []; + + /** + * @inheritdoc + */ + public function log($level, $message, array $context = []) + { + $record = [ + 'level' => $level, + 'message' => $message, + 'context' => $context, + ]; + + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + public function hasRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + public function hasRecord($record, $level) + { + if (is_string($record)) { + $record = ['message' => $record]; + } + return $this->hasRecordThatPasses(function ($rec) use ($record) { + if ($rec['message'] !== $record['message']) { + return false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return false; + } + return true; + }, $level); + } + + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($message) { + return strpos($rec['message'], $message) !== false; + }, $level); + } + + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return preg_match($regex, $rec['message']) > 0; + }, $level); + } + + public function hasRecordThatPasses(callable $predicate, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (call_user_func($predicate, $rec, $i)) { + return true; + } + } + return false; + } + + public function __call($method, $args) + { + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + $level = strtolower($matches[2]); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + return call_user_func_array([$this, $genericMethod], $args); + } + } + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } + + public function reset() + { + $this->records = []; + $this->recordsByLevel = []; + } + +} \ No newline at end of file diff --git a/tests/src/TestLogger/TestLoggerV2V3.php b/tests/src/TestLogger/TestLoggerV2V3.php new file mode 100644 index 0000000..a65e516 --- /dev/null +++ b/tests/src/TestLogger/TestLoggerV2V3.php @@ -0,0 +1,338 @@ + + * @license GPLv2+ + * @link https://www.inpsyde.com + */ + +namespace Inpsyde\Wonolog\Tests\TestLogger; + +use Psr\Log\LoggerInterface; +use Psr\Log\LoggerTrait; + +class TestLoggerV2V3 implements LoggerInterface +{ + use LoggerTrait; + + public array $records = []; + public array $recordsByLevel = []; + + /** + * @inheritdoc + */ + public function log($level, $message, array $context = []): void + { + $record = [ + 'level' => $level, + 'message' => $message, + 'context' => $context, + ]; + + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + /** + * @param string $level + * @return bool + */ + public function hasRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + /** + * @param array $record + * @param string $level + * @return bool + */ + public function hasRecord($record, $level) + { + if (is_string($record)) { + $record = ['message' => $record]; + } + + return $this->hasRecordThatPasses(function ($rec) use ($record) { + if ($rec['message'] !== $record['message']) { + return false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return false; + } + return true; + }, $level); + } + + /** + * @param string $message + * @param string $level + * @return bool + */ + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(fn ($rec) => str_contains($rec['message'], $message), $level); + } + + /** + * @param string $regex + * @param string $level + * @return bool + */ + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(fn ($rec) => preg_match($regex, $rec['message']) > 0, $level); + } + + /** + * @param callable $predicate + * @param string $level + * @return bool + */ + public function hasRecordThatPasses(callable $predicate, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if ($predicate($rec, $i)) { + return true; + } + } + + return false; + } + + /** + * @deprecated Since psr/log-util 1.1 + */ + public function __call($method, $args) + { + @trigger_error(sprintf('Since psr/log-util 1.1: Method "%s" is deprecated and should not be called. Use method "%s" instead.', __FUNCTION__, $method), \E_USER_DEPRECATED); + + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + $level = strtolower($matches[2]); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + return call_user_func_array([$this, $genericMethod], $args); + } + } + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } + + public function hasEmergency($record): bool + { + return $this->hasRecord($record, 'emergency'); + } + + public function hasAlert($record): bool + { + return $this->hasRecord($record, 'alert'); + } + + public function hasCritical($record): bool + { + return $this->hasRecord($record, 'critical'); + } + + public function hasError($record): bool + { + return $this->hasRecord($record, 'error'); + } + + public function hasWarning($record): bool + { + return $this->hasRecord($record, 'warning'); + } + + public function hasNotice($record): bool + { + return $this->hasRecord($record, 'notice'); + } + + public function hasInfo($record): bool + { + return $this->hasRecord($record, 'info'); + } + + public function hasDebug($record): bool + { + return $this->hasRecord($record, 'debug'); + } + + public function hasEmergencyRecords(): bool + { + return $this->hasRecords('emergency'); + } + + public function hasAlertRecords(): bool + { + return $this->hasRecords('alert'); + } + + public function hasCriticalRecords(): bool + { + return $this->hasRecords('critical'); + } + + public function hasErrorRecords(): bool + { + return $this->hasRecords('error'); + } + + public function hasWarningRecords(): bool + { + return $this->hasRecords('warning'); + } + + public function hasNoticeRecords(): bool + { + return $this->hasRecords('notice'); + } + + public function hasInfoRecords(): bool + { + return $this->hasRecords('info'); + } + + public function hasDebugRecords(): bool + { + return $this->hasRecords('debug'); + } + + public function hasEmergencyThatContains($message): bool + { + return $this->hasRecordThatContains($message, 'emergency'); + } + + public function hasAlertThatContains($message): bool + { + return $this->hasRecordThatContains($message, 'alert'); + } + + public function hasCriticalThatContains($message): bool + { + return $this->hasRecordThatContains($message, 'critical'); + } + + public function hasErrorThatContains($message): bool + { + return $this->hasRecordThatContains($message, 'error'); + } + + public function hasWarningThatContains($message): bool + { + return $this->hasRecordThatContains($message, 'warning'); + } + + public function hasNoticeThatContains($message): bool + { + return $this->hasRecordThatContains($message, 'notice'); + } + + public function hasInfoThatContains($message): bool + { + return $this->hasRecordThatContains($message, 'info'); + } + + public function hasDebugThatContains($message): bool + { + return $this->hasRecordThatContains($message, 'debug'); + } + + public function hasEmergencyThatMatches(string $regex): bool + { + return $this->hasRecordThatMatches($regex, 'emergency'); + } + + public function hasAlertThatMatches(string $regex): bool + { + return $this->hasRecordThatMatches($regex, 'alert'); + } + + public function hasCriticalThatMatches(string $regex): bool + { + return $this->hasRecordThatMatches($regex, 'critical'); + } + + public function hasErrorThatMatches(string $regex): bool + { + return $this->hasRecordThatMatches($regex, 'error'); + } + + public function hasWarningThatMatches(string $regex): bool + { + return $this->hasRecordThatMatches($regex, 'warning'); + } + + public function hasNoticeThatMatches(string $regex): bool + { + return $this->hasRecordThatMatches($regex, 'notice'); + } + + public function hasInfoThatMatches(string $regex): bool + { + return $this->hasRecordThatMatches($regex, 'info'); + } + + public function hasDebugThatMatches(string $regex): bool + { + return $this->hasRecordThatMatches($regex, 'debug'); + } + + public function hasEmergencyThatPasses(callable $predicate): bool + { + return $this->hasRecordThatPasses($predicate, 'emergency'); + } + + public function hasAlertThatPasses(callable $predicate): bool + { + return $this->hasRecordThatPasses($predicate, 'alert'); + } + + public function hasCriticalThatPasses(callable $predicate): bool + { + return $this->hasRecordThatPasses($predicate, 'critical'); + } + + public function hasErrorThatPasses(callable $predicate): bool + { + return $this->hasRecordThatPasses($predicate, 'error'); + } + + public function hasWarningThatPasses(callable $predicate): bool + { + return $this->hasRecordThatPasses($predicate, 'warning'); + } + + public function hasNoticeThatPasses(callable $predicate): bool + { + return $this->hasRecordThatPasses($predicate, 'notice'); + } + + public function hasInfoThatPasses(callable $predicate): bool + { + return $this->hasRecordThatPasses($predicate, 'info'); + } + + public function hasDebugThatPasses(callable $predicate): bool + { + return $this->hasRecordThatPasses($predicate, 'debug'); + } + + public function reset() + { + $this->records = []; + $this->recordsByLevel = []; + } +} \ No newline at end of file diff --git a/tests/unit/LogActionUpdaterTest.php b/tests/unit/LogActionUpdaterTest.php index 21b86a5..73c7eb9 100644 --- a/tests/unit/LogActionUpdaterTest.php +++ b/tests/unit/LogActionUpdaterTest.php @@ -10,6 +10,8 @@ use Inpsyde\Wonolog\Data\Log; use Inpsyde\Wonolog\LogActionUpdater; use Inpsyde\Wonolog\LogLevel as WonologLogLevel; +use Inpsyde\Wonolog\Tests\TestLogger\TestLoggerV1; +use Inpsyde\Wonolog\Tests\TestLogger\TestLoggerV2V3; use Inpsyde\Wonolog\Tests\UnitTestCase; use Monolog\Logger; use Psr\Log\LogLevel; @@ -94,7 +96,8 @@ public function testUpdateLogsUsingPsrLogger(): void $log = new Log('Test me', Logger::EMERGENCY, Channels::SECURITY, ['foo' => 'bar']); - $logger = new TestLogger(); + + $logger = $this->buildLogger(); $channels = \Mockery::mock(Channels::class); $channels->expects('isIgnored')->with($log)->andReturn(false); @@ -145,7 +148,7 @@ public function testUpdateLogsUsingPsrLoggerWithMaskedInput(): void $log = new Log('Test me', Logger::EMERGENCY, Channels::SECURITY, $context); - $logger = new TestLogger(); + $logger = $this->buildLogger(); $channels = \Mockery::mock(Channels::class); $channels->expects('isIgnored')->with($log)->andReturn(false); @@ -160,4 +163,9 @@ public function testUpdateLogsUsingPsrLoggerWithMaskedInput(): void static::assertSame(LogLevel::EMERGENCY, $record['level']); static::assertSame($contextExpected, $record['context']); } + + private function buildLogger() + { + return version_compare(phpversion(), '8.0') ? new TestLoggerV2V3() : new TestLoggerV1(); + } } From 2454a6c0244330ff3a95309fb4a20b996b3a989a Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Tue, 28 Nov 2023 19:12:30 +0100 Subject: [PATCH 14/20] ci: added php 7 compat --- .github/workflows/php-integration-tests.yml | 2 +- .github/workflows/php-static-analysis.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/php-integration-tests.yml b/.github/workflows/php-integration-tests.yml index 8bc1032..338cf1f 100644 --- a/.github/workflows/php-integration-tests.yml +++ b/.github/workflows/php-integration-tests.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - php-service: [ '80', '81', '82' ] + php-service: [ '72', '73', '74', '80', '81', '82' ] steps: - name: Checkout uses: actions/checkout@v3 diff --git a/.github/workflows/php-static-analysis.yml b/.github/workflows/php-static-analysis.yml index 2f084cb..52daf10 100644 --- a/.github/workflows/php-static-analysis.yml +++ b/.github/workflows/php-static-analysis.yml @@ -31,7 +31,7 @@ jobs: uses: inpsyde/reusable-workflows/.github/workflows/lint-php.yml@main if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run lint only')) }} with: - PHP_MATRIX: '["8.0", "8.1", "8.2"]' + PHP_MATRIX: '["7.4", "8.0", "8.1", "8.2"]' coding-standards-analysis-php: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} @@ -44,6 +44,6 @@ jobs: uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main strategy: matrix: - php-version: [ '8.0', '8.1', '8.2' ] + php-version: [ '7.4', '8.0', '8.1', '8.2' ] with: PHP_VERSION: ${{ matrix.php-version }} From 942bc0b7de3585881c9f7d672f5019020ed667ea Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Tue, 28 Nov 2023 19:16:02 +0100 Subject: [PATCH 15/20] chore: return back older php 7 versions be more explicit in the supported versions --- .github/workflows/php-static-analysis.yml | 4 ++-- composer.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/php-static-analysis.yml b/.github/workflows/php-static-analysis.yml index 52daf10..b0ab3f1 100644 --- a/.github/workflows/php-static-analysis.yml +++ b/.github/workflows/php-static-analysis.yml @@ -31,7 +31,7 @@ jobs: uses: inpsyde/reusable-workflows/.github/workflows/lint-php.yml@main if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run lint only')) }} with: - PHP_MATRIX: '["7.4", "8.0", "8.1", "8.2"]' + PHP_MATRIX: '["7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]' coding-standards-analysis-php: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} @@ -44,6 +44,6 @@ jobs: uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main strategy: matrix: - php-version: [ '7.4', '8.0', '8.1', '8.2' ] + php-version: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2' ] with: PHP_VERSION: ${{ matrix.php-version }} diff --git a/composer.json b/composer.json index f37c383..61a0de7 100644 --- a/composer.json +++ b/composer.json @@ -37,8 +37,8 @@ } ], "require": { - "php": "^7.4||>=8.0 < 8.3", - "psr/log": ">1.0.1 <2.0||^2.0||^3.0", + "php": ">=7.2||>=8.0 < 8.3", + "psr/log": ">=1.0.1 <2.0||^2.0||^3.0", "wecodemore/wordpress-early-hook": "^1.1.0", "monolog/monolog": ">=2.0.1 <3" }, From 45bdd5574acbafe8b7e9e1bff944b2c68471beb2 Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Tue, 28 Nov 2023 19:17:10 +0100 Subject: [PATCH 16/20] chore: add missing versions --- .github/workflows/php-unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/php-unit-tests.yml b/.github/workflows/php-unit-tests.yml index b3ad1a9..884f752 100644 --- a/.github/workflows/php-unit-tests.yml +++ b/.github/workflows/php-unit-tests.yml @@ -25,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: [ '7.4', '8.0', '8.1', '8.2' ] + php-versions: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2' ] dependency-versions: ['highest', 'lowest'] steps: From 98a74fc609aadacd64f5ea361054509574dc1056 Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Tue, 28 Nov 2023 19:21:59 +0100 Subject: [PATCH 17/20] chore: droping support for older php versions --- .github/workflows/php-integration-tests.yml | 2 +- .github/workflows/php-static-analysis.yml | 4 ++-- .github/workflows/php-unit-tests.yml | 2 +- composer.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/php-integration-tests.yml b/.github/workflows/php-integration-tests.yml index 338cf1f..6b8f656 100644 --- a/.github/workflows/php-integration-tests.yml +++ b/.github/workflows/php-integration-tests.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - php-service: [ '72', '73', '74', '80', '81', '82' ] + php-service: [ '74', '80', '81', '82' ] steps: - name: Checkout uses: actions/checkout@v3 diff --git a/.github/workflows/php-static-analysis.yml b/.github/workflows/php-static-analysis.yml index b0ab3f1..52daf10 100644 --- a/.github/workflows/php-static-analysis.yml +++ b/.github/workflows/php-static-analysis.yml @@ -31,7 +31,7 @@ jobs: uses: inpsyde/reusable-workflows/.github/workflows/lint-php.yml@main if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run lint only')) }} with: - PHP_MATRIX: '["7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]' + PHP_MATRIX: '["7.4", "8.0", "8.1", "8.2"]' coding-standards-analysis-php: if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only')) }} @@ -44,6 +44,6 @@ jobs: uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main strategy: matrix: - php-version: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2' ] + php-version: [ '7.4', '8.0', '8.1', '8.2' ] with: PHP_VERSION: ${{ matrix.php-version }} diff --git a/.github/workflows/php-unit-tests.yml b/.github/workflows/php-unit-tests.yml index 884f752..b3ad1a9 100644 --- a/.github/workflows/php-unit-tests.yml +++ b/.github/workflows/php-unit-tests.yml @@ -25,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2' ] + php-versions: [ '7.4', '8.0', '8.1', '8.2' ] dependency-versions: ['highest', 'lowest'] steps: diff --git a/composer.json b/composer.json index 61a0de7..6447c09 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ } ], "require": { - "php": ">=7.2||>=8.0 < 8.3", + "php": "^7.4||>=8.0 < 8.3", "psr/log": ">=1.0.1 <2.0||^2.0||^3.0", "wecodemore/wordpress-early-hook": "^1.1.0", "monolog/monolog": ">=2.0.1 <3" From 8281d3f1b9279c2adea3f87b80c7c995ca39f20b Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Tue, 28 Nov 2023 19:40:41 +0100 Subject: [PATCH 18/20] chore: fixing CS errors --- composer.json | 1 + tests/src/TestLogger/AbstractLoggerV1.php | 18 +++++++------- tests/src/TestLogger/TestLoggerV1.php | 29 ++++++++++++++++------- tests/src/TestLogger/TestLoggerV2V3.php | 8 +++++-- 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/composer.json b/composer.json index 6447c09..80599d6 100644 --- a/composer.json +++ b/composer.json @@ -88,6 +88,7 @@ }, "scripts": { "cs": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs", + "cs:fix": "@php ./vendor/bin/phpcbf", "psalm": "@php ./vendor/vimeo/psalm/psalm --no-suggestions --find-unused-psalm-suppress --no-diff --no-cache --no-file-cache", "tests:unit": "@php ./vendor/phpunit/phpunit/phpunit --testsuite=unit", "tests:unit:no-cov": "@php ./vendor/phpunit/phpunit/phpunit --testsuite=unit --no-coverage", diff --git a/tests/src/TestLogger/AbstractLoggerV1.php b/tests/src/TestLogger/AbstractLoggerV1.php index 8a774b9..c293393 100644 --- a/tests/src/TestLogger/AbstractLoggerV1.php +++ b/tests/src/TestLogger/AbstractLoggerV1.php @@ -30,7 +30,7 @@ abstract class AbstractLoggerV1 implements LoggerInterface * * @return void */ - public function emergency($message, array $context = array()) + public function emergency($message, array $context = []) { $this->log(LogLevel::EMERGENCY, $message, $context); } @@ -46,7 +46,7 @@ public function emergency($message, array $context = array()) * * @return void */ - public function alert($message, array $context = array()) + public function alert($message, array $context = []) { $this->log(LogLevel::ALERT, $message, $context); } @@ -61,7 +61,7 @@ public function alert($message, array $context = array()) * * @return void */ - public function critical($message, array $context = array()) + public function critical($message, array $context = []) { $this->log(LogLevel::CRITICAL, $message, $context); } @@ -75,7 +75,7 @@ public function critical($message, array $context = array()) * * @return void */ - public function error($message, array $context = array()) + public function error($message, array $context = []) { $this->log(LogLevel::ERROR, $message, $context); } @@ -91,7 +91,7 @@ public function error($message, array $context = array()) * * @return void */ - public function warning($message, array $context = array()) + public function warning($message, array $context = []) { $this->log(LogLevel::WARNING, $message, $context); } @@ -104,7 +104,7 @@ public function warning($message, array $context = array()) * * @return void */ - public function notice($message, array $context = array()) + public function notice($message, array $context = []) { $this->log(LogLevel::NOTICE, $message, $context); } @@ -119,7 +119,7 @@ public function notice($message, array $context = array()) * * @return void */ - public function info($message, array $context = array()) + public function info($message, array $context = []) { $this->log(LogLevel::INFO, $message, $context); } @@ -132,8 +132,8 @@ public function info($message, array $context = array()) * * @return void */ - public function debug($message, array $context = array()) + public function debug($message, array $context = []) { $this->log(LogLevel::DEBUG, $message, $context); } -} \ No newline at end of file +} diff --git a/tests/src/TestLogger/TestLoggerV1.php b/tests/src/TestLogger/TestLoggerV1.php index 3006293..3b80870 100644 --- a/tests/src/TestLogger/TestLoggerV1.php +++ b/tests/src/TestLogger/TestLoggerV1.php @@ -72,8 +72,10 @@ class TestLoggerV1 extends AbstractLoggerV1 /** * @var array */ + // phpcs:ignore Inpsyde.CodeQuality.ForbiddenPublicProperty.Found public $records = []; + // phpcs:ignore Inpsyde.CodeQuality.ForbiddenPublicProperty.Found public $recordsByLevel = []; /** @@ -101,7 +103,7 @@ public function hasRecord($record, $level) if (is_string($record)) { $record = ['message' => $record]; } - return $this->hasRecordThatPasses(function ($rec) use ($record) { + return $this->hasRecordThatPasses(static function ($rec) use ($record) { if ($rec['message'] !== $record['message']) { return false; } @@ -114,14 +116,14 @@ public function hasRecord($record, $level) public function hasRecordThatContains($message, $level) { - return $this->hasRecordThatPasses(function ($rec) use ($message) { + return $this->hasRecordThatPasses(static function ($rec) use ($message) { return strpos($rec['message'], $message) !== false; }, $level); } public function hasRecordThatMatches($regex, $level) { - return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return $this->hasRecordThatPasses(static function ($rec) use ($regex) { return preg_match($regex, $rec['message']) > 0; }, $level); } @@ -132,6 +134,7 @@ public function hasRecordThatPasses(callable $predicate, $level) return false; } foreach ($this->recordsByLevel[$level] as $i => $rec) { + // phpcs:ignore NeutronStandard.Functions.DisallowCallUserFunc.CallUserFunc if (call_user_func($predicate, $rec, $i)) { return true; } @@ -141,15 +144,26 @@ public function hasRecordThatPasses(callable $predicate, $level) public function __call($method, $args) { - if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { - $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + if ( + preg_match( + '/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', + $method, + $matches + ) > 0 + ) { + $genericMethod = $matches[1] + . ('Records' !== $matches[3] ? 'Record' : '') + . $matches[3]; $level = strtolower($matches[2]); if (method_exists($this, $genericMethod)) { $args[] = $level; + // phpcs:ignore NeutronStandard.Functions.DisallowCallUserFunc.CallUserFunc return call_user_func_array([$this, $genericMethod], $args); } } - throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + throw new \BadMethodCallException( + 'Call to undefined method ' . get_class($this) . '::' . $method . '()' + ); } public function reset() @@ -157,5 +171,4 @@ public function reset() $this->records = []; $this->recordsByLevel = []; } - -} \ No newline at end of file +} diff --git a/tests/src/TestLogger/TestLoggerV2V3.php b/tests/src/TestLogger/TestLoggerV2V3.php index a65e516..9534464 100644 --- a/tests/src/TestLogger/TestLoggerV2V3.php +++ b/tests/src/TestLogger/TestLoggerV2V3.php @@ -24,7 +24,10 @@ class TestLoggerV2V3 implements LoggerInterface { use LoggerTrait; + // phpcs:ignore Inpsyde.CodeQuality.ForbiddenPublicProperty.Found, PHPCompatibility.Classes.NewTypedProperties.Found public array $records = []; + + // phpcs:ignore Inpsyde.CodeQuality.ForbiddenPublicProperty.Found, PHPCompatibility.Classes.NewTypedProperties.Found public array $recordsByLevel = []; /** @@ -62,7 +65,7 @@ public function hasRecord($record, $level) $record = ['message' => $record]; } - return $this->hasRecordThatPasses(function ($rec) use ($record) { + return $this->hasRecordThatPasses(static function ($rec) use ($record) { if ($rec['message'] !== $record['message']) { return false; } @@ -117,6 +120,7 @@ public function hasRecordThatPasses(callable $predicate, $level) */ public function __call($method, $args) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped @trigger_error(sprintf('Since psr/log-util 1.1: Method "%s" is deprecated and should not be called. Use method "%s" instead.', __FUNCTION__, $method), \E_USER_DEPRECATED); if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { @@ -335,4 +339,4 @@ public function reset() $this->records = []; $this->recordsByLevel = []; } -} \ No newline at end of file +} From 9ca121de98bfbe734dd5d51d3899e016e37fd8d0 Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Tue, 28 Nov 2023 19:50:36 +0100 Subject: [PATCH 19/20] chore: fix line length and ignore some complaints in CS --- tests/src/TestLogger/TestLoggerV2V3.php | 42 ++++++++++++++++++++----- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/tests/src/TestLogger/TestLoggerV2V3.php b/tests/src/TestLogger/TestLoggerV2V3.php index 9534464..046124e 100644 --- a/tests/src/TestLogger/TestLoggerV2V3.php +++ b/tests/src/TestLogger/TestLoggerV2V3.php @@ -83,7 +83,10 @@ public function hasRecord($record, $level) */ public function hasRecordThatContains($message, $level) { - return $this->hasRecordThatPasses(fn ($rec) => str_contains($rec['message'], $message), $level); + return $this->hasRecordThatPasses( + fn ($rec) => str_contains($rec['message'], $message), + $level + ); } /** @@ -93,7 +96,10 @@ public function hasRecordThatContains($message, $level) */ public function hasRecordThatMatches($regex, $level) { - return $this->hasRecordThatPasses(fn ($rec) => preg_match($regex, $rec['message']) > 0, $level); + return $this->hasRecordThatPasses( + fn ($rec) => preg_match($regex, $rec['message']) > 0, + $level + ); } /** @@ -120,18 +126,38 @@ public function hasRecordThatPasses(callable $predicate, $level) */ public function __call($method, $args) { - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - @trigger_error(sprintf('Since psr/log-util 1.1: Method "%s" is deprecated and should not be called. Use method "%s" instead.', __FUNCTION__, $method), \E_USER_DEPRECATED); - - if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { - $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged + @trigger_error( + sprintf( + // phpcs:ignore Inpsyde.CodeQuality.LineLength.TooLong + 'Since psr/log-util 1.1: Method "%s" is deprecated and should not be called. Use method "%s" instead.', + __FUNCTION__, + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + $method + ), + \E_USER_DEPRECATED + ); + + if ( + preg_match( + '/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', + $method, + $matches + ) > 0 + ) { + $genericMethod = $matches[1] + . ('Records' !== $matches[3] ? 'Record' : '') + . $matches[3]; $level = strtolower($matches[2]); if (method_exists($this, $genericMethod)) { $args[] = $level; + // phpcs:ignore NeutronStandard.Functions.DisallowCallUserFunc.CallUserFunc return call_user_func_array([$this, $genericMethod], $args); } } - throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + throw new \BadMethodCallException( + 'Call to undefined method ' . get_class($this) . '::' . $method . '()' + ); } public function hasEmergency($record): bool From 8e3dba0bafeba35bb7dd60a8a73887d2504c0099 Mon Sep 17 00:00:00 2001 From: Luis Rosales Date: Thu, 14 Dec 2023 11:35:29 +0100 Subject: [PATCH 20/20] chore: add missing comparator --- tests/unit/LogActionUpdaterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/LogActionUpdaterTest.php b/tests/unit/LogActionUpdaterTest.php index 73c7eb9..9248f83 100644 --- a/tests/unit/LogActionUpdaterTest.php +++ b/tests/unit/LogActionUpdaterTest.php @@ -166,6 +166,6 @@ public function testUpdateLogsUsingPsrLoggerWithMaskedInput(): void private function buildLogger() { - return version_compare(phpversion(), '8.0') ? new TestLoggerV2V3() : new TestLoggerV1(); + return version_compare(phpversion(), '8.0', '>=') ? new TestLoggerV2V3() : new TestLoggerV1(); } }