diff --git a/composer.json b/composer.json
index 5c2674f..52a50d8 100644
--- a/composer.json
+++ b/composer.json
@@ -11,11 +11,16 @@
"email": "info@karmabunny.com.au"
}
],
+ "config": {
+ "platform": {
+ "php": "8.2"
+ }
+ },
"require": {
"symfony/polyfill-php73": "*",
- "php": "^7.2|^8",
+ "php": "^8.2",
"symfony/polyfill-php81": "^1.26",
- "karmabunny/interfaces": "^1.2"
+ "karmabunny/interfaces": "dev-feat/php8"
},
"require-dev": {
"phpunit/phpunit": "^9.3",
diff --git a/composer.lock b/composer.lock
index 7499a97..4bc6de1 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,24 +4,24 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "3250080f6aa48c9395618cd62548d528",
+ "content-hash": "e78215c5cc91fefd1f05b60276ecddc6",
"packages": [
{
"name": "karmabunny/interfaces",
- "version": "v1.2.1",
+ "version": "dev-feat/php8",
"source": {
"type": "git",
"url": "https://github.com/Karmabunny/kbinterfaces.git",
- "reference": "dcf87a7013dbdb29c66480d3bdb8561d1167e0fe"
+ "reference": "0119a8b95d97f96c60651f93b237e4960b94fcb1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Karmabunny/kbinterfaces/zipball/dcf87a7013dbdb29c66480d3bdb8561d1167e0fe",
- "reference": "dcf87a7013dbdb29c66480d3bdb8561d1167e0fe",
+ "url": "https://api.github.com/repos/Karmabunny/kbinterfaces/zipball/0119a8b95d97f96c60651f93b237e4960b94fcb1",
+ "reference": "0119a8b95d97f96c60651f93b237e4960b94fcb1",
"shasum": ""
},
"require": {
- "php": "^7.2|^8"
+ "php": "^8.2"
},
"require-dev": {
"phpcompatibility/php-compatibility": "^9.3",
@@ -53,35 +53,32 @@
],
"support": {
"issues": "https://github.com/Karmabunny/kbinterfaces/issues",
- "source": "https://github.com/Karmabunny/kbinterfaces/tree/v1.2.1"
+ "source": "https://github.com/Karmabunny/kbinterfaces/tree/feat/php8"
},
- "time": "2026-01-28T01:05:13+00:00"
+ "time": "2026-07-17T03:10:22+00:00"
},
{
"name": "symfony/polyfill-php73",
- "version": "v1.28.0",
+ "version": "v1.37.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
- "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5"
+ "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5",
- "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb",
+ "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=7.2"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
@@ -118,7 +115,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.37.0"
},
"funding": [
{
@@ -129,38 +126,39 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-php81",
- "version": "v1.28.0",
+ "version": "v1.38.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
- "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b"
+ "reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b",
- "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b",
+ "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/6bfb9c766cacffbc8e118cb87217d08ed84e5cd7",
+ "reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=7.2"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
@@ -197,7 +195,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php81/tree/v1.38.1"
},
"funding": [
{
@@ -208,12 +206,16 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2026-05-26T12:45:58+00:00"
}
],
"packages-dev": [
@@ -289,16 +291,16 @@
},
{
"name": "myclabs/deep-copy",
- "version": "1.11.1",
+ "version": "1.13.4",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
+ "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
- "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
+ "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
"shasum": ""
},
"require": {
@@ -306,11 +308,12 @@
},
"conflict": {
"doctrine/collections": "<1.6.8",
- "doctrine/common": "<2.13.3 || >=3,<3.2.2"
+ "doctrine/common": "<2.13.3 || >=3 <3.2.2"
},
"require-dev": {
"doctrine/collections": "^1.6.8",
"doctrine/common": "^2.13.3 || ^3.2.2",
+ "phpspec/prophecy": "^1.10",
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
},
"type": "library",
@@ -336,7 +339,7 @@
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
- "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
},
"funding": [
{
@@ -344,29 +347,30 @@
"type": "tidelift"
}
],
- "time": "2023-03-08T13:26:56+00:00"
+ "time": "2025-08-01T08:46:24+00:00"
},
{
"name": "nikic/php-parser",
- "version": "v4.17.1",
+ "version": "v5.8.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
+ "reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
- "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/044a6a392ff8ad0d61f14370a5fbbd0a0107152f",
+ "reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f",
"shasum": ""
},
"require": {
+ "ext-json": "*",
"ext-tokenizer": "*",
- "php": ">=7.0"
+ "php": ">=7.4"
},
"require-dev": {
"ircmaxell/php-yacc": "^0.0.7",
- "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ "phpunit/phpunit": "^9.0"
},
"bin": [
"bin/php-parse"
@@ -374,7 +378,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.9-dev"
+ "dev-master": "5.x-dev"
}
},
"autoload": {
@@ -398,26 +402,27 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
+ "source": "https://github.com/nikic/PHP-Parser/tree/v5.8.0"
},
- "time": "2023-08-13T19:53:39+00:00"
+ "time": "2026-07-04T14:30:18+00:00"
},
{
"name": "phar-io/manifest",
- "version": "2.0.3",
+ "version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/phar-io/manifest.git",
- "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
+ "reference": "54750ef60c58e43759730615a392c31c80e23176"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
- "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
+ "reference": "54750ef60c58e43759730615a392c31c80e23176",
"shasum": ""
},
"require": {
"ext-dom": "*",
+ "ext-libxml": "*",
"ext-phar": "*",
"ext-xmlwriter": "*",
"phar-io/version": "^3.0.1",
@@ -458,9 +463,15 @@
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
"support": {
"issues": "https://github.com/phar-io/manifest/issues",
- "source": "https://github.com/phar-io/manifest/tree/2.0.3"
+ "source": "https://github.com/phar-io/manifest/tree/2.0.4"
},
- "time": "2021-07-20T11:28:43+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-03T12:33:53+00:00"
},
{
"name": "phar-io/version",
@@ -577,16 +588,11 @@
},
{
"name": "phpstan/phpstan",
- "version": "2.1.13",
- "source": {
- "type": "git",
- "url": "https://github.com/phpstan/phpstan.git",
- "reference": "e55e03e6d4ac49cd1240907e5b08e5cd378572a9"
- },
+ "version": "2.2.5",
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e55e03e6d4ac49cd1240907e5b08e5cd378572a9",
- "reference": "e55e03e6d4ac49cd1240907e5b08e5cd378572a9",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/909c1e5fef7989ac0d0c1c5c42e32a5c4f6198a0",
+ "reference": "909c1e5fef7989ac0d0c1c5c42e32a5c4f6198a0",
"shasum": ""
},
"require": {
@@ -609,6 +615,17 @@
"license": [
"MIT"
],
+ "authors": [
+ {
+ "name": "Ondřej Mirtes"
+ },
+ {
+ "name": "Markus Staab"
+ },
+ {
+ "name": "Vincent Langlet"
+ }
+ ],
"description": "PHPStan - PHP Static Analysis Tool",
"keywords": [
"dev",
@@ -631,39 +648,39 @@
"type": "github"
}
],
- "time": "2025-04-27T12:28:25+00:00"
+ "time": "2026-07-05T06:31:06+00:00"
},
{
"name": "phpunit/php-code-coverage",
- "version": "9.2.29",
+ "version": "9.2.32",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76"
+ "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76",
- "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5",
+ "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"ext-xmlwriter": "*",
- "nikic/php-parser": "^4.15",
+ "nikic/php-parser": "^4.19.1 || ^5.1.0",
"php": ">=7.3",
- "phpunit/php-file-iterator": "^3.0.3",
- "phpunit/php-text-template": "^2.0.2",
- "sebastian/code-unit-reverse-lookup": "^2.0.2",
- "sebastian/complexity": "^2.0",
- "sebastian/environment": "^5.1.2",
- "sebastian/lines-of-code": "^1.0.3",
- "sebastian/version": "^3.0.1",
- "theseer/tokenizer": "^1.2.0"
+ "phpunit/php-file-iterator": "^3.0.6",
+ "phpunit/php-text-template": "^2.0.4",
+ "sebastian/code-unit-reverse-lookup": "^2.0.3",
+ "sebastian/complexity": "^2.0.3",
+ "sebastian/environment": "^5.1.5",
+ "sebastian/lines-of-code": "^1.0.4",
+ "sebastian/version": "^3.0.2",
+ "theseer/tokenizer": "^1.2.3"
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^9.6"
},
"suggest": {
"ext-pcov": "PHP extension that provides line coverage",
@@ -672,7 +689,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "9.2-dev"
+ "dev-main": "9.2.x-dev"
}
},
"autoload": {
@@ -701,7 +718,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
- "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29"
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32"
},
"funding": [
{
@@ -709,7 +726,7 @@
"type": "github"
}
],
- "time": "2023-09-19T04:57:46+00:00"
+ "time": "2024-08-22T04:23:01+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -954,45 +971,45 @@
},
{
"name": "phpunit/phpunit",
- "version": "9.6.13",
+ "version": "9.6.35",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be"
+ "reference": "0edba2f3a0c48df3553cb9b640810b30df60302b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be",
- "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0edba2f3a0c48df3553cb9b640810b30df60302b",
+ "reference": "0edba2f3a0c48df3553cb9b640810b30df60302b",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.3.1 || ^2",
+ "doctrine/instantiator": "^1.5.0 || ^2",
"ext-dom": "*",
+ "ext-filter": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
- "ext-xml": "*",
"ext-xmlwriter": "*",
- "myclabs/deep-copy": "^1.10.1",
- "phar-io/manifest": "^2.0.3",
- "phar-io/version": "^3.0.2",
+ "myclabs/deep-copy": "^1.13.4",
+ "phar-io/manifest": "^2.0.4",
+ "phar-io/version": "^3.2.1",
"php": ">=7.3",
- "phpunit/php-code-coverage": "^9.2.28",
- "phpunit/php-file-iterator": "^3.0.5",
+ "phpunit/php-code-coverage": "^9.2.32",
+ "phpunit/php-file-iterator": "^3.0.6",
"phpunit/php-invoker": "^3.1.1",
- "phpunit/php-text-template": "^2.0.3",
- "phpunit/php-timer": "^5.0.2",
- "sebastian/cli-parser": "^1.0.1",
- "sebastian/code-unit": "^1.0.6",
- "sebastian/comparator": "^4.0.8",
- "sebastian/diff": "^4.0.3",
- "sebastian/environment": "^5.1.3",
- "sebastian/exporter": "^4.0.5",
- "sebastian/global-state": "^5.0.1",
- "sebastian/object-enumerator": "^4.0.3",
- "sebastian/resource-operations": "^3.0.3",
- "sebastian/type": "^3.2",
+ "phpunit/php-text-template": "^2.0.4",
+ "phpunit/php-timer": "^5.0.3",
+ "sebastian/cli-parser": "^1.0.2",
+ "sebastian/code-unit": "^1.0.8",
+ "sebastian/comparator": "^4.0.10",
+ "sebastian/diff": "^4.0.6",
+ "sebastian/environment": "^5.1.5",
+ "sebastian/exporter": "^4.0.8",
+ "sebastian/global-state": "^5.0.8",
+ "sebastian/object-enumerator": "^4.0.4",
+ "sebastian/resource-operations": "^3.0.4",
+ "sebastian/type": "^3.2.1",
"sebastian/version": "^3.0.2"
},
"suggest": {
@@ -1037,36 +1054,28 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.35"
},
"funding": [
{
- "url": "https://phpunit.de/sponsors.html",
- "type": "custom"
- },
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
- "type": "tidelift"
+ "url": "https://phpunit.de/sponsoring.html",
+ "type": "other"
}
],
- "time": "2023-09-19T05:39:22+00:00"
+ "time": "2026-07-06T14:48:07+00:00"
},
{
"name": "sebastian/cli-parser",
- "version": "1.0.1",
+ "version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/cli-parser.git",
- "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
+ "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
- "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
+ "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
"shasum": ""
},
"require": {
@@ -1101,7 +1110,7 @@
"homepage": "https://github.com/sebastianbergmann/cli-parser",
"support": {
"issues": "https://github.com/sebastianbergmann/cli-parser/issues",
- "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2"
},
"funding": [
{
@@ -1109,7 +1118,7 @@
"type": "github"
}
],
- "time": "2020-09-28T06:08:49+00:00"
+ "time": "2024-03-02T06:27:43+00:00"
},
{
"name": "sebastian/code-unit",
@@ -1224,16 +1233,16 @@
},
{
"name": "sebastian/comparator",
- "version": "4.0.8",
+ "version": "4.0.10",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "fa0f136dd2334583309d32b62544682ee972b51a"
+ "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a",
- "reference": "fa0f136dd2334583309d32b62544682ee972b51a",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d",
+ "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d",
"shasum": ""
},
"require": {
@@ -1286,32 +1295,44 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
- "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8"
+ "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.10"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
+ },
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
+ "type": "tidelift"
}
],
- "time": "2022-09-14T12:41:17+00:00"
+ "time": "2026-01-24T09:22:56+00:00"
},
{
"name": "sebastian/complexity",
- "version": "2.0.2",
+ "version": "2.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/complexity.git",
- "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
+ "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
- "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a",
+ "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a",
"shasum": ""
},
"require": {
- "nikic/php-parser": "^4.7",
+ "nikic/php-parser": "^4.18 || ^5.0",
"php": ">=7.3"
},
"require-dev": {
@@ -1343,7 +1364,7 @@
"homepage": "https://github.com/sebastianbergmann/complexity",
"support": {
"issues": "https://github.com/sebastianbergmann/complexity/issues",
- "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
+ "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3"
},
"funding": [
{
@@ -1351,20 +1372,20 @@
"type": "github"
}
],
- "time": "2020-10-26T15:52:27+00:00"
+ "time": "2023-12-22T06:19:30+00:00"
},
{
"name": "sebastian/diff",
- "version": "4.0.5",
+ "version": "4.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131"
+ "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
- "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc",
+ "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc",
"shasum": ""
},
"require": {
@@ -1409,7 +1430,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
- "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5"
+ "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6"
},
"funding": [
{
@@ -1417,7 +1438,7 @@
"type": "github"
}
],
- "time": "2023-05-07T05:35:17+00:00"
+ "time": "2024-03-02T06:30:58+00:00"
},
{
"name": "sebastian/environment",
@@ -1484,16 +1505,16 @@
},
{
"name": "sebastian/exporter",
- "version": "4.0.5",
+ "version": "4.0.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d"
+ "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
- "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/14c6ba52f95a36c3d27c835d65efc7123c446e8c",
+ "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c",
"shasum": ""
},
"require": {
@@ -1549,28 +1570,40 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
- "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5"
+ "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.8"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
+ },
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter",
+ "type": "tidelift"
}
],
- "time": "2022-09-14T06:03:37+00:00"
+ "time": "2025-09-24T06:03:27+00:00"
},
{
"name": "sebastian/global-state",
- "version": "5.0.6",
+ "version": "5.0.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "bde739e7565280bda77be70044ac1047bc007e34"
+ "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34",
- "reference": "bde739e7565280bda77be70044ac1047bc007e34",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
+ "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
"shasum": ""
},
"require": {
@@ -1613,32 +1646,44 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
- "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6"
+ "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
+ },
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state",
+ "type": "tidelift"
}
],
- "time": "2023-08-02T09:26:13+00:00"
+ "time": "2025-08-10T07:10:35+00:00"
},
{
"name": "sebastian/lines-of-code",
- "version": "1.0.3",
+ "version": "1.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/lines-of-code.git",
- "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
+ "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
- "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5",
+ "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5",
"shasum": ""
},
"require": {
- "nikic/php-parser": "^4.6",
+ "nikic/php-parser": "^4.18 || ^5.0",
"php": ">=7.3"
},
"require-dev": {
@@ -1670,7 +1715,7 @@
"homepage": "https://github.com/sebastianbergmann/lines-of-code",
"support": {
"issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
- "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
+ "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4"
},
"funding": [
{
@@ -1678,7 +1723,7 @@
"type": "github"
}
],
- "time": "2020-11-28T06:42:11+00:00"
+ "time": "2023-12-22T06:20:34+00:00"
},
{
"name": "sebastian/object-enumerator",
@@ -1794,16 +1839,16 @@
},
{
"name": "sebastian/recursion-context",
- "version": "4.0.5",
+ "version": "4.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"
+ "reference": "539c6691e0623af6dc6f9c20384c120f963465a0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
- "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0",
+ "reference": "539c6691e0623af6dc6f9c20384c120f963465a0",
"shasum": ""
},
"require": {
@@ -1845,28 +1890,40 @@
"homepage": "https://github.com/sebastianbergmann/recursion-context",
"support": {
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
- "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5"
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
+ },
+ {
+ "url": "https://liberapay.com/sebastianbergmann",
+ "type": "liberapay"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/sebastianbergmann",
+ "type": "thanks_dev"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
+ "type": "tidelift"
}
],
- "time": "2023-02-03T06:07:39+00:00"
+ "time": "2025-08-10T06:57:39+00:00"
},
{
"name": "sebastian/resource-operations",
- "version": "3.0.3",
+ "version": "3.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/resource-operations.git",
- "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
+ "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
- "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
+ "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
"shasum": ""
},
"require": {
@@ -1878,7 +1935,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-main": "3.0-dev"
}
},
"autoload": {
@@ -1899,8 +1956,7 @@
"description": "Provides a list of PHP built-in functions that operate on resources",
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
"support": {
- "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
- "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4"
},
"funding": [
{
@@ -1908,7 +1964,7 @@
"type": "github"
}
],
- "time": "2020-09-28T06:45:17+00:00"
+ "time": "2024-03-14T16:00:52+00:00"
},
{
"name": "sebastian/type",
@@ -2021,16 +2077,16 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "3.7.2",
+ "version": "3.13.5",
"source": {
"type": "git",
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
- "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
+ "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
- "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
+ "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0ca86845ce43291e8f5692c7356fccf3bcf02bf4",
+ "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4",
"shasum": ""
},
"require": {
@@ -2040,18 +2096,13 @@
"php": ">=5.4.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4"
},
"bin": [
- "bin/phpcs",
- "bin/phpcbf"
+ "bin/phpcbf",
+ "bin/phpcs"
],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.x-dev"
- }
- },
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
@@ -2059,35 +2110,62 @@
"authors": [
{
"name": "Greg Sherwood",
- "role": "lead"
+ "role": "Former lead"
+ },
+ {
+ "name": "Juliette Reinders Folmer",
+ "role": "Current lead"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors"
}
],
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
- "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
"keywords": [
"phpcs",
"standards",
"static analysis"
],
"support": {
- "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
- "source": "https://github.com/squizlabs/PHP_CodeSniffer",
- "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
+ "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues",
+ "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy",
+ "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
+ "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki"
},
- "time": "2023-02-22T23:07:41+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/PHPCSStandards",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/jrfnl",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/php_codesniffer",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/phpcsstandards",
+ "type": "thanks_dev"
+ }
+ ],
+ "time": "2025-11-04T16:30:35+00:00"
},
{
"name": "theseer/tokenizer",
- "version": "1.2.1",
+ "version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
- "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
+ "reference": "b7489ce515e168639d17feec34b8847c326b0b3c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
- "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c",
+ "reference": "b7489ce515e168639d17feec34b8847c326b0b3c",
"shasum": ""
},
"require": {
@@ -2116,7 +2194,7 @@
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
"issues": "https://github.com/theseer/tokenizer/issues",
- "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
+ "source": "https://github.com/theseer/tokenizer/tree/1.3.1"
},
"funding": [
{
@@ -2124,17 +2202,22 @@
"type": "github"
}
],
- "time": "2021-07-28T10:34:58+00:00"
+ "time": "2025-11-17T20:03:58+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
- "stability-flags": {},
+ "stability-flags": {
+ "karmabunny/interfaces": 20
+ },
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": "^7.2|^8"
+ "php": "^8.2"
},
"platform-dev": {},
+ "platform-overrides": {
+ "php": "8.2"
+ },
"plugin-api-version": "2.6.0"
}
diff --git a/phpcs.xml b/phpcs.xml
index 2cbd096..297154d 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -8,7 +8,7 @@
src
-
+
diff --git a/phpstan.neon b/phpstan.neon
index 2b523b3..1549053 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,8 +1,8 @@
parameters:
level: 5
phpVersion:
- min: 70200
- max: 80400
+ min: 80200
+ max: 80500
paths:
- src
ignoreErrors:
diff --git a/src/ArrayAccessTrait.php b/src/ArrayAccessTrait.php
index fc38892..f85ced5 100644
--- a/src/ArrayAccessTrait.php
+++ b/src/ArrayAccessTrait.php
@@ -6,35 +6,33 @@
namespace karmabunny\kb;
-use ReturnTypeWillChange;
+/**
+ * @mixin \ArrayAccess
+ */
trait ArrayAccessTrait
{
- #[ReturnTypeWillChange]
- public function offsetExists($offset)
+ public function offsetExists(mixed $offset): bool
{
return isset($this->$offset);
}
- #[ReturnTypeWillChange]
- public function offsetGet($offset)
+ public function offsetGet(mixed $offset): mixed
{
return $this->$offset ?? null;
}
- #[ReturnTypeWillChange]
- public function offsetSet($offset, $value)
+ public function offsetSet(mixed $offset, mixed $value): void
{
$this->$offset = $value;
}
- #[ReturnTypeWillChange]
- public function offsetUnset($offset)
+ public function offsetUnset(mixed $offset): void
{
unset($this->$offset);
}
diff --git a/src/Arrays.php b/src/Arrays.php
index 8532e07..816cc85 100644
--- a/src/Arrays.php
+++ b/src/Arrays.php
@@ -1,4 +1,5 @@
$item) {
return [$key, $item];
@@ -67,7 +68,7 @@ public static function firstPair($iterable)
* @param iterable $iterable
* @return array [ key, item ]
*/
- public static function lastPair($iterable)
+ public static function lastPair(iterable $iterable): array
{
if (is_array($iterable)) {
$item = end($iterable);
@@ -90,7 +91,7 @@ public static function lastPair($iterable)
* @param iterable $iterable
* @return int|string|null
*/
- public static function firstKey($iterable)
+ public static function firstKey(iterable $iterable): int|string|null
{
list($key) = self::firstPair($iterable);
return $key;
@@ -103,7 +104,7 @@ public static function firstKey($iterable)
* @param iterable $iterable
* @return int|string|null
*/
- public static function lastKey($iterable)
+ public static function lastKey(iterable $iterable): int|string|null
{
list($key) = self::lastPair($iterable);
return $key;
@@ -117,7 +118,7 @@ public static function lastKey($iterable)
* @param T[]|iterable $iterable
* @return T|null
*/
- public static function first($iterable)
+ public static function first(iterable $iterable): mixed
{
list( , $value) = self::firstPair($iterable);
return $value;
@@ -131,7 +132,7 @@ public static function first($iterable)
* @param T[]|iterable $iterable
* @return T|null
*/
- public static function last($iterable)
+ public static function last(iterable $iterable): mixed
{
list( , $value) = self::lastPair($iterable);
return $value;
@@ -150,10 +151,10 @@ public static function last($iterable)
* TBH not entirely sure why I wrote this.
*
* @template T
- * @param T[]|iterable $array
+ * @param iterable $array
* @return iterable
*/
- public static function reverse($array)
+ public static function reverse(iterable $array): iterable
{
end($array);
while (($key = key($array)) !== null)
@@ -185,7 +186,7 @@ public static function reverse($array)
* @param callable $fn (&$index) => $value
* @return array
*/
- public static function fill(int $size, callable $fn)
+ public static function fill(int $size, callable $fn): array
{
$array = [];
for ($i = 0; $i < $size; $i++) {
@@ -212,7 +213,7 @@ public static function fill(int $size, callable $fn)
* @param callable $fn ($index) => [$key, $value]
* @return array
*/
- public static function fillKeyed(int $size, callable $fn)
+ public static function fillKeyed(int $size, callable $fn): array
{
$array = [];
for ($i = 0; $i < $size; $i++) {
@@ -240,7 +241,7 @@ public static function fillKeyed(int $size, callable $fn)
* @param mixed $fill
* @return array
*/
- public static function fillIntersectionKeys(array $keys, array $array, $fill = null)
+ public static function fillIntersectionKeys(array $keys, array $array, mixed $fill = null): array
{
$keys = array_fill_keys($keys, $fill);
$array = array_merge($keys, array_intersect_key($array, $keys));
@@ -259,7 +260,7 @@ public static function fillIntersectionKeys(array $keys, array $array, $fill = n
* @param string $inner_glue
* @return string
*/
- public static function implodeWithKeys(array $array, string $outer_glue = '', string $inner_glue = '')
+ public static function implodeWithKeys(array $array, string $outer_glue = '', string $inner_glue = ''): string
{
$output = '';
@@ -280,7 +281,7 @@ public static function implodeWithKeys(array $array, string $outer_glue = '', st
* @param T|null $initial
* @return T
*/
- public static function reverseReduce($array, $fn, $initial = null)
+ public static function reverseReduce(iterable $array, callable $fn, mixed $initial = null): mixed
{
$reversed = self::reverse($array);
$carry = $initial;
@@ -309,7 +310,7 @@ public static function reverseReduce($array, $fn, $initial = null)
* @param array $arrays
* @return array
*/
- public static function mergeKeyed(...$arrays)
+ public static function mergeKeyed(array ...$arrays): array
{
$reversed = self::reverse($arrays);
@@ -341,7 +342,7 @@ public static function mergeKeyed(...$arrays)
* @param callable $fn ($value, $key) => bool
* @return T|null
*/
- public static function find($iterable, callable $fn)
+ public static function find(iterable $iterable, callable $fn): mixed
{
foreach ($iterable as $key => $item) {
if ($fn($item, $key)) return $item;
@@ -363,7 +364,7 @@ public static function find($iterable, callable $fn)
* @param callable $fn ($value, $key) => bool
* @return T|null
*/
- public static function findKey($iterable, callable $fn)
+ public static function findKey(iterable $iterable, callable $fn): mixed
{
foreach ($iterable as $key => $item) {
if ($fn($item, $key)) return $key;
@@ -380,7 +381,7 @@ public static function findKey($iterable, callable $fn)
* @param string $key
* @return null|int
*/
- public static function indexOf(array $array, string $key)
+ public static function indexOf(array $array, string $key): ?int
{
$index = array_search($key, array_keys($array));
@@ -408,7 +409,7 @@ public static function indexOf(array $array, string $key)
* @param mixed|null $initial
* @return mixed
*/
- public static function reduce($iterable, callable $fn, $initial = null)
+ public static function reduce(iterable $iterable, callable $fn, mixed $initial = null): mixed
{
$carry = $initial;
foreach ($iterable as $key => $value) {
@@ -510,7 +511,7 @@ public static function filterRecursive(array $array, ?callable $callback = null,
* @param bool $fill Replace missing keys with null.
* @return T[]
*/
- public static function filterKeys(array $array, array $keys, $fill = false): array
+ public static function filterKeys(array $array, array $keys, bool $fill = false): array
{
$items = [];
@@ -529,7 +530,7 @@ public static function filterKeys(array $array, array $keys, $fill = false): arr
* @param iterable $arrays
* @return array
*/
- public static function zip(...$arrays): array
+ public static function zip(iterable ...$arrays): array
{
$output = [];
@@ -577,7 +578,7 @@ public static function zip(...$arrays): array
* @param callable $fn (item) => item
* @return array
*/
- public static function map($array, $fn): array
+ public static function map(iterable $array, callable $fn): array
{
$items = [];
@@ -613,7 +614,7 @@ public static function map($array, $fn): array
* @param callable $fn (item, key) => item
* @return array
*/
- public static function mapWithKeys($array, $fn): array
+ public static function mapWithKeys(iterable $array, callable $fn): array
{
$items = [];
@@ -640,7 +641,7 @@ public static function mapWithKeys($array, $fn): array
* @param callable $fn (item, key) => [key, item]
* @return array
*/
- public static function mapKeys($array, $fn): array
+ public static function mapKeys(iterable $array, callable $fn): array
{
$items = [];
@@ -667,7 +668,7 @@ public static function mapKeys($array, $fn): array
* @param int $mode LEAVES_ONLY (default), SELF_FIRST, CHILD_FIRST
* @return array
*/
- public static function mapRecursive(array $array, $fn, $mode = self::LEAVES_ONLY): array
+ public static function mapRecursive(array $array, callable $fn, int $mode = self::LEAVES_ONLY): array
{
$process = null;
$process = function($rootkey, array $array, $fn, $mode) use (&$process) {
@@ -712,7 +713,7 @@ public static function mapRecursive(array $array, $fn, $mode = self::LEAVES_ONLY
* @param bool $preserve_keys
* @return T[]
*/
- public static function shuffle($array, bool $preserve_keys = false): array
+ public static function shuffle(iterable $array, bool $preserve_keys = false): array
{
if (!is_array($array)) {
$array = iterator_to_array($array, $preserve_keys);
@@ -744,7 +745,7 @@ public static function shuffle($array, bool $preserve_keys = false): array
* @param int $depth
* @return array
*/
- public static function flatten($array, $keys = false, int $depth = 25): array
+ public static function flatten(iterable $array, bool $keys = false, int $depth = 25): array
{
$return = [];
@@ -865,7 +866,7 @@ public static function flattenKeys(array $array, string $glue = '.'): array
* @param string|int $index
* @return array
*/
- public static function explodeKeys(array $array, string $glue = '.', $index = ''): array
+ public static function explodeKeys(array $array, string $glue = '.', string|int $index = ''): array
{
$output = [];
@@ -905,7 +906,6 @@ public static function explodeKeys(array $array, string $glue = '.', $index = ''
}
// A root index key is a bit of an edge-case.
- // @phpstan-ignore-next-line : Doesn't like all the reference business.
if ($index !== '' and isset($output[''])) {
$output = [ $index => $output[''] ] + $output;
unset($output['']);
@@ -920,16 +920,20 @@ public static function explodeKeys(array $array, string $glue = '.', $index = ''
*
* This converts any nested arrayables to arrays.
*
- * @param ArrayableInterface|Traversable|array $array
+ * @param object|array $array
* @param bool $recurse - recurse into nested arrays
* @return array
*/
- public static function toArray($array, bool $recurse = true): array
+ public static function toArray(object|array $array, bool $recurse = true): array
{
if ($array instanceof ArrayableInterface) {
return $array->toArray();
}
+ if (is_object($array) and !$array instanceof Traversable) {
+ $array = (array) $array;
+ }
+
foreach ($array as &$item) {
if ($item instanceof ArrayableInterface) {
$item = $item->toArray();
@@ -974,7 +978,7 @@ public static function toArray($array, bool $recurse = true): array
* @param mixed $array
* @return bool
*/
- public static function isNumeric($array): bool
+ public static function isNumeric(mixed $array): bool
{
if (!is_array($array)) {
return false;
@@ -999,7 +1003,7 @@ public static function isNumeric($array): bool
* @param mixed $array
* @return bool
*/
- public static function isAssociated($array): bool
+ public static function isAssociated(mixed $array): bool
{
return !self::isNumeric($array);
}
@@ -1039,7 +1043,7 @@ public static function isAssociated($array): bool
* @param array $array
* @return mixed
*/
- public static function value($array, string $query)
+ public static function value(mixed $array, string $query): mixed
{
/** @var mixed $array */
@@ -1126,7 +1130,7 @@ public static function value($array, string $query)
* @param string|null $select Include a 'choose' option
* @return array
*/
- public static function createMap($items, string $key, string $name, ?string $select = null)
+ public static function createMap(iterable $items, string $key, string $name, ?string $select = null): array
{
$map = [];
@@ -1184,7 +1188,7 @@ public static function createMap($items, string $key, string $name, ?string $sel
* @param mixed $default
* @return array
*/
- public static function normalizeOptions($items, $default): array
+ public static function normalizeOptions(iterable $items, mixed $default): array
{
$output = [];
@@ -1225,7 +1229,7 @@ public static function normalizeOptions($items, $default): array
* @param string $path
* @return array|null `null` if the file is invalid or missing.
*/
- public static function config(string $path)
+ public static function config(string $path): ?array
{
static $cache = [];
$output = $cache[$path] ?? null;
@@ -1261,7 +1265,7 @@ public static function config(string $path)
* @param string|null $mode null => 'default'
* @return callable(mixed, mixed): int
*/
- public static function createSort(int $dir = SORT_ASC, ?string $mode = null)
+ public static function createSort(int $dir = SORT_ASC, ?string $mode = null): callable
{
$dir = $dir === SORT_DESC ? -1 : 1;
@@ -1336,7 +1340,7 @@ public static function createSort(int $dir = SORT_ASC, ?string $mode = null)
* @param array $modes [ name => SORT ]
* @return callable(mixed, mixed): int
*/
- public static function createMultisort(array $modes)
+ public static function createMultisort(array $modes): callable
{
$modes = self::normalizeOptions($modes, SORT_ASC);
@@ -1366,7 +1370,7 @@ public static function createMultisort(array $modes)
* @param string|null $mode null => 'default'
* @return void
*/
- public static function sort(array &$array, bool $preserve_keys = false, int $dir = SORT_ASC, ?string $mode = null)
+ public static function sort(array &$array, bool $preserve_keys = false, int $dir = SORT_ASC, ?string $mode = null): void
{
$fn = self::createSort($dir, $mode);
@@ -1408,7 +1412,7 @@ public static function sorted(array $array, bool $preserve_keys = false, int $di
* @param string[] $modes [ name => SORT ]
* @return void
*/
- public static function multisort(array &$array, bool $preserve_keys, array $modes)
+ public static function multisort(array &$array, bool $preserve_keys, array $modes): void
{
$fn = self::createMultisort($modes);
@@ -1431,7 +1435,7 @@ public static function multisort(array &$array, bool $preserve_keys, array $mode
* @param string[] $modes [ name => SORT ]
* @return T[]
*/
- public static function multisorted(array $array, bool $preserve_keys, array $modes)
+ public static function multisorted(array $array, bool $preserve_keys, array $modes): array
{
self::multisort($array, $preserve_keys, $modes);
return $array;
diff --git a/src/AttributeTag.php b/src/AttributeTag.php
index a96f541..4457e55 100644
--- a/src/AttributeTag.php
+++ b/src/AttributeTag.php
@@ -1,4 +1,5 @@
getAttributes(static::class, ReflectionAttribute::IS_INSTANCEOF);
$tags = [];
@@ -231,7 +210,7 @@ public static function parseReflectorAttributes($reflect): array
* @param ReflectionClass|ReflectionFunctionAbstract|ReflectionProperty|ReflectionClassConstant|ReflectionParameter $reflect
* @return static[]
*/
- public static function parseReflectorDocTags($reflect): array
+ public static function parseReflectorDocTags(Reflector $reflect): array
{
// Static store for class metadata. This only needs to be parsed once.
// A bit of inception here. We're parsing the @doctags of the tag
diff --git a/src/BaseRule.php b/src/BaseRule.php
index 839ebb8..d546236 100644
--- a/src/BaseRule.php
+++ b/src/BaseRule.php
@@ -29,11 +29,11 @@ abstract class BaseRule implements RuleInterface
{
/** @var string[] */
- public $fields = [];
+ public array $fields = [];
/** @inheritdoc */
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
$this->fields = [];
@@ -69,7 +69,7 @@ public function fields(): array
/** @inheritdoc */
- public function validate($data)
+ public function validate(array|object $data): void
{
if (is_object($data) and !$data instanceof ArrayAccess) {
$data = new ArrayObject($data, ArrayObject::STD_PROP_LIST | ArrayObject::ARRAY_AS_PROPS);
@@ -119,7 +119,7 @@ public function validate($data)
* @param mixed $value
* @return void
*/
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
}
@@ -130,7 +130,7 @@ public function validateOne(string $field, $value)
* @param array|object $data
* @return array
*/
- public function getFieldValues($data): array
+ public function getFieldValues(array|object $data): array
{
if (is_object($data) and !$data instanceof ArrayAccess) {
$data = new ArrayObject($data, ArrayObject::STD_PROP_LIST | ArrayObject::ARRAY_AS_PROPS);
@@ -159,7 +159,7 @@ public function getFieldValues($data): array
* @param string $field
* @return bool
*/
- public static function isEmpty($data, string $field): bool
+ public static function isEmpty(array|ArrayAccess $data, string $field): bool
{
$value = $data[$field] ?? null;
diff --git a/src/Buffer.php b/src/Buffer.php
index 7ca8d8d..bac4bcc 100644
--- a/src/Buffer.php
+++ b/src/Buffer.php
@@ -1,4 +1,5 @@
level() > 0) {
throw new RuntimeException('Buffer is already open');
@@ -102,7 +103,7 @@ public function flush(bool $send = true)
*
* @return void
*/
- public function discard()
+ public function discard(): void
{
if (!$this->level()) {
return;
@@ -224,7 +225,7 @@ public function end(bool $flush = true): void
*
* @return void
*/
- public static function closeAll()
+ public static function closeAll(): void
{
while (ob_get_level()) ob_end_clean();
}
@@ -235,7 +236,7 @@ public static function closeAll()
*
* @return void
*/
- public static function flushAll()
+ public static function flushAll(): void
{
while (ob_get_level()) ob_end_flush();
}
diff --git a/src/CachedHelperTrait.php b/src/CachedHelperTrait.php
index 133c1a0..a259108 100644
--- a/src/CachedHelperTrait.php
+++ b/src/CachedHelperTrait.php
@@ -44,7 +44,7 @@ trait CachedHelperTrait
* @param string|null $key
* @return void
*/
- protected function clearCache(?string $key = null)
+ protected function clearCache(?string $key = null): void
{
if ($key) {
unset($this->_cache[$key]);
@@ -109,7 +109,7 @@ protected function getCachedIterable(string $id, $fn): array
* @param callable $fn () => mixed
* @return mixed function result
*/
- protected function getCachedValue(string $id, $fn)
+ protected function getCachedValue(string $id, $fn): mixed
{
if (!array_key_exists($id, $this->_cache)) {
$this->_cache[$id] = $fn();
@@ -129,7 +129,7 @@ protected function getCachedValue(string $id, $fn)
* @param mixed $fn (...$inputs) => mixed
* @return mixed
*/
- protected function getCachedResult(array $inputs, $fn)
+ protected function getCachedResult(array $inputs, $fn): mixed
{
$key = sha1(serialize($inputs));
diff --git a/src/CallbackRule.php b/src/CallbackRule.php
index 885ae23..0a19ee0 100644
--- a/src/CallbackRule.php
+++ b/src/CallbackRule.php
@@ -20,16 +20,16 @@ class CallbackRule extends BaseRule
{
/** @var callable|null */
- public $callable;
+ public mixed $callable = null;
/** @var array */
- public $args = [];
+ public array $args = [];
- public $multi = false;
+ public bool $multi = false;
/** @inheritdoc */
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
parent::parse($ruleset);
@@ -44,7 +44,7 @@ public function parse(array $ruleset)
/** @inheritdoc */
- public function validate($data)
+ public function validate(array|object $data): void
{
if (!$this->callable or empty($this->fields)) {
return;
@@ -61,7 +61,7 @@ public function validate($data)
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if (!$this->callable) {
return;
diff --git a/src/Cli.php b/src/Cli.php
index 4aad675..74ccdc1 100644
--- a/src/Cli.php
+++ b/src/Cli.php
@@ -1,4 +1,5 @@
getSerializedProperties();
}
diff --git a/src/Config.php b/src/Config.php
index 7f890c1..fda1b0e 100644
--- a/src/Config.php
+++ b/src/Config.php
@@ -1,4 +1,5 @@
name => instance */
- protected static $instances = [];
+ protected static array $instances = [];
/** @var array name => [key => value] */
- protected $overrides = [];
+ protected array $overrides = [];
/** @var array name => config */
- protected $cache = [];
+ protected array $cache = [];
/** @var array name => [paths] */
- protected $loaded = [];
+ protected array $loaded = [];
/**
* Get or create an instance of this config.
*
- * @param bool $refresh
- * @return static
*/
- public static function instance(bool $refresh = false)
+ public static function instance(bool $refresh = false): static
{
$instance = self::$instances[static::class] ?? null;
@@ -74,11 +73,9 @@ public abstract function getPaths(): array;
/**
* Does this config exist?
*
- * @param string $name
- * @return string[]
* @throws InvalidArgumentException on an invalid config name.
*/
- public function find(string $name)
+ public function find(string $name): array
{
if (preg_match('![^-_a-zA-Z0-9]!', $name)) {
throw new InvalidArgumentException("Invalid config file '{$name}'");
@@ -100,6 +97,7 @@ public function find(string $name)
/**
* Load and merge configs.
*
+ * @param array $config
* @param string $path
* @param string $name
* @return bool
@@ -171,7 +169,7 @@ public static function load(string $path, string $name = 'config'): array
* @throws InvalidArgumentException When a config doesn't exist.
* @throws RuntimeException if a recursive config file is detected.
*/
- public static function get(string $key, $required = true)
+ public static function get(string $key, bool $required = true): mixed
{
$instance = static::instance();
[$name, $subkey] = explode('.', $key, 2) + ['', null];
@@ -222,7 +220,7 @@ public static function get(string $key, $required = true)
* @param mixed $value
* @return void
*/
- public static function set(string $key, $value)
+ public static function set(string $key, mixed $value): void
{
$instance = static::instance();
[$name, $key] = explode('.', $key, 2) + ['', null];
@@ -237,7 +235,7 @@ public static function set(string $key, $value)
* @param string $query dot-noted string: foo.bar.baz
* @return mixed|null
*/
- public static function query(array $array, string $query)
+ public static function query(array $array, string $query): mixed
{
if (empty($array)) {
return null;
@@ -282,7 +280,7 @@ public static function query(array $array, string $query)
* @param mixed $value fill value for the key
* @return void
*/
- public static function querySet(array &$array, string $query, $value = null)
+ public static function querySet(array &$array, string $query, mixed $value = null): void
{
if (empty($query)) {
return;
diff --git a/src/Configure.php b/src/Configure.php
index a9809b4..82c29bf 100644
--- a/src/Configure.php
+++ b/src/Configure.php
@@ -1,4 +1,5 @@
$class
* @param class-string|class-string[] $assert
* @return T
* @throws InvalidArgumentException
*/
- public static function instance(string $class, $assert = null)
+ public static function instance(string $class, string|array|null $assert = null): object
{
// Check the class exists.
try {
@@ -199,7 +200,7 @@ public static function instance(string $class, $assert = null)
* @param array $config
* @return void
*/
- public static function update($object, array $config)
+ public static function update(object $object, array $config): void
{
// Do configurable things because we can.
if ($object instanceof ConfigurableInterface) {
@@ -223,12 +224,12 @@ public static function update($object, array $config)
/**
* Instance a single object.
*
- * @template T
+ * @template T of object
* @param class-string $class
* @param array $config
* @return T
*/
- public static function create(string $class, array $config)
+ public static function create(string $class, array $config): object
{
$object = self::instance($class);
self::update($object, $config);
@@ -244,7 +245,7 @@ public static function create(string $class, array $config)
* @param array[] $items
* @return T[]
*/
- public static function createAll(string $class, array $items)
+ public static function createAll(string $class, array $items): array
{
/** @var array $items */
diff --git a/src/ConfigureTrait.php b/src/ConfigureTrait.php
index 374a047..e3ca7f7 100644
--- a/src/ConfigureTrait.php
+++ b/src/ConfigureTrait.php
@@ -43,7 +43,7 @@ trait ConfigureTrait
* @return object
* @throws InvalidArgumentException
*/
- public static function configure($config, ?string $assert = null, bool $init = true)
+ public static function configure($config, ?string $assert = null, bool $init = true): object
{
return Configure::configure($config, $assert, $init);
}
diff --git a/src/CountryNames.php b/src/CountryNames.php
index 65086f3..092c481 100644
--- a/src/CountryNames.php
+++ b/src/CountryNames.php
@@ -299,7 +299,7 @@ public static function getAlpha3(): array
* @param string $code alpha-2
* @return string|null alpha-3
*/
- public static function getAlpha3From2(string $code)
+ public static function getAlpha3From2(string $code): ?string
{
$code = strtoupper(trim($code));
if (strlen($code) == 3) return $code;
@@ -313,7 +313,7 @@ public static function getAlpha3From2(string $code)
* @param string $code alpha-3
* @return string|null alpha-2
*/
- public static function getAlpha2From3(string $code)
+ public static function getAlpha2From3(string $code): ?string
{
$code = strtoupper(trim($code));
if (strlen($code) == 2) return $code;
@@ -329,7 +329,7 @@ public static function getAlpha2From3(string $code)
* @param string $language default 'en'
* @return string|null
*/
- public static function getCountryCode(string $country_name, string $language = 'en')
+ public static function getCountryCode(string $country_name, string $language = 'en'): ?string
{
if (strlen($language) != 2) return null;
$language = strtoupper($language);
@@ -369,7 +369,7 @@ public static function getCountryCode(string $country_name, string $language = '
* @param string $language default 'en'
* @return string|null
*/
- public static function getCountryName(string $country_code, string $language = 'en')
+ public static function getCountryName(string $country_code, string $language = 'en'): ?string
{
if (strlen($language) != 2) return null;
$language = strtoupper($language);
diff --git a/src/CountryZones.php b/src/CountryZones.php
index 11ebdb4..58e0fb1 100644
--- a/src/CountryZones.php
+++ b/src/CountryZones.php
@@ -80,7 +80,7 @@ public static function getZones(string $country): array
* @param bool $alpha3
* @return null|string
*/
- public static function lookup(string $zone, $alpha3 = false): ?string
+ public static function lookup(string $zone, bool $alpha3 = false): ?string
{
$map = self::getMap();
$zone = $map[$zone] ?? null;
diff --git a/src/CsvExport.php b/src/CsvExport.php
index b6ca2ab..7b6fa52 100644
--- a/src/CsvExport.php
+++ b/src/CsvExport.php
@@ -27,34 +27,34 @@ class CsvExport
const DIRTY_CHARS = ' "\r\n\t';
/** @var resource */
- public $handle;
+ public mixed $handle;
/** @var array */
- public $formatters = [];
+ public array $formatters = [];
/** @var string Only supported in PHP 8.1+ */
- public $break = "\n";
+ public string $break = "\n";
/** @var string */
- public $delimiter = ',';
+ public string $delimiter = ',';
/** @var string */
- public $null = '\N';
+ public string $null = '\N';
/** @var string */
- public $enclosure = '"';
+ public string $enclosure = '"';
/** @var string */
- public $escape = '\\';
+ public string $escape = '\\';
/** @var array|null */
- public $headers = null;
+ public array|null $headers = null;
/** @var string */
- private $dirty_re;
+ private string $dirty_re;
/** @var bool */
- private $_own_handles = false;
+ private bool $_own_handles = false;
/**
* Configure the CSV output format.
@@ -235,8 +235,6 @@ private function _format(string $attribute, $value): string
try {
$value = @(string) $value;
}
- // We're told that __toString() shouldn't throw, but that doesn't mean it can't.
- // @phpstan-ignore-next-line
catch (Throwable $exception) {
$value = 'ERR';
}
@@ -298,25 +296,13 @@ protected function _write(array $row)
$items[$key] = $this->_format($key, $value);
}
- if (PHP_VERSION_ID > 80100) {
- // @phpstan-ignore-next-line : newer PHP has more fields.
- fputcsv(
- $this->handle,
- $items,
- $this->delimiter,
- $this->enclosure,
- $this->escape,
- $this->break
- );
- }
- else {
- fputcsv(
- $this->handle,
- $items,
- $this->delimiter,
- $this->enclosure,
- $this->escape
- );
- }
+ fputcsv(
+ $this->handle,
+ $items,
+ $this->delimiter,
+ $this->enclosure,
+ $this->escape,
+ $this->break
+ );
}
}
diff --git a/src/CsvImport.php b/src/CsvImport.php
index e06fe49..9cc25c5 100644
--- a/src/CsvImport.php
+++ b/src/CsvImport.php
@@ -24,31 +24,31 @@ class CsvImport implements IteratorAggregate
const MAX_MEMORY = 5 * 1024 * 1024;
/** @var string */
- public $break = "\n";
+ public string $break = "\n";
/** @var string */
- public $delimiter = ',';
+ public string $delimiter = ',';
/** @var string */
- public $null = '\N';
+ public string $null = '\N';
/** @var string */
- public $enclosure = '"';
+ public string $enclosure = '"';
/** @var string */
- public $escape = '\\';
+ public string $escape = '\\';
/** @var array|null */
- public $headers = null;
+ public array|null $headers = null;
/** @var bool This importer manages it's own handles. */
- private $_own_handles = false;
+ private bool $_own_handles = false;
/** @var string */
- private $_escape_re;
+ private string $_escape_re;
/** @var resource|null */
- private $handle;
+ private mixed $handle = null;
/**
* Configure the CSV output format.
@@ -82,14 +82,14 @@ public function __construct($handle, $config = [])
*
* @param string $filename
* @param array $config
- * @return null|CsvImport
+ * @return null|self
*/
- public static function fromFile(string $filename, $config = [])
+ public static function fromFile(string $filename, $config = []): ?self
{
$handle = @fopen($filename, 'r');
if ($handle === false) return null;
- $importer = new CsvImport($handle, $config);
+ $importer = new self($handle, $config);
$importer->_own_handles = true;
return $importer;
}
@@ -100,9 +100,9 @@ public static function fromFile(string $filename, $config = [])
*
* @param string $csv
* @param array $config
- * @return null|CsvImport
+ * @return null|self
*/
- public static function fromString(string $csv, $config = [])
+ public static function fromString(string $csv, $config = []): ?self
{
$handle = @fopen('php://temp/maxmemory:' . self::MAX_MEMORY, 'r+');
if ($handle === false) return null;
@@ -110,7 +110,7 @@ public static function fromString(string $csv, $config = [])
fputs($handle, $csv);
rewind($handle);
- $importer = new CsvImport($handle, $config);
+ $importer = new self($handle, $config);
$importer->_own_handles = true;
return $importer;
}
@@ -149,7 +149,7 @@ public function getHeaders(): array
*
* @return null|array An associated array or null if EOF.
*/
- public function getLine()
+ public function getLine(): ?array
{
// Load in headers from the first row.
$this->getHeaders();
@@ -186,7 +186,7 @@ public function getIterator(): Traversable
*
* @return null|array row values or null if EOF.
*/
- private function _getcsv()
+ private function _getcsv(): ?array
{
if ($this->handle === null) return null;
diff --git a/src/DataObject.php b/src/DataObject.php
index 9a6a0b3..f84e792 100644
--- a/src/DataObject.php
+++ b/src/DataObject.php
@@ -28,7 +28,7 @@ abstract class DataObject implements ConfigurableInterface
/**
* @param iterable $config
*/
- function __construct($config = [])
+ function __construct(iterable $config = [])
{
// This makes things not break. Something about references.
if (!is_array($config)) {
diff --git a/src/DirtyChecksums.php b/src/DirtyChecksums.php
index d69818c..4fc4c7d 100644
--- a/src/DirtyChecksums.php
+++ b/src/DirtyChecksums.php
@@ -19,10 +19,10 @@ class DirtyChecksums implements NotSerializable
{
/** @var string[] [ name => sha ] */
- public $checksums = [];
+ public array $checksums = [];
/** @var object */
- public $target;
+ public object $target;
/**
@@ -47,7 +47,7 @@ public function __construct($target)
* @param mixed $value
* @return string
*/
- protected function getChecksum($value): string
+ protected function getChecksum(mixed $value): string
{
if (
$value === null
@@ -94,7 +94,7 @@ protected function getProperties(): Traversable
*
* @return void
*/
- public function reset()
+ public function reset(): void
{
$this->checksums = [];
}
@@ -107,7 +107,7 @@ public function reset()
*
* @return void
*/
- public function update()
+ public function update(): void
{
foreach ($this->getProperties() as $name => $value) {
$this->checksums[$name] = $this->getChecksum($value);
@@ -135,7 +135,7 @@ public function updateField(string $name)
* @param string $name
* @return void
*/
- public function markDirty(string $name)
+ public function markDirty(string $name): void
{
if (property_exists($this->target, $name)) {
$this->checksums[$name] = 'DIRTY';
@@ -149,7 +149,7 @@ public function markDirty(string $name)
* @param string $name
* @return bool
*/
- public function isDirty(string $name)
+ public function isDirty(string $name): bool
{
// Don't know about this one. Not dirty.
if (!property_exists($this->target, $name)) {
diff --git a/src/DocType.php b/src/DocType.php
index 2ad6956..1abe15c 100644
--- a/src/DocType.php
+++ b/src/DocType.php
@@ -19,16 +19,16 @@
class DocType extends Collection
{
/** @var string */
- public $name;
+ public string $name;
/** @var string */
- public $comment;
+ public string $comment;
/** @var mixed */
- public $value;
+ public mixed $value;
/** @var string[]|null */
- private $_doc_types;
+ private array|null $_doc_types = null;
/**
@@ -62,7 +62,7 @@ public function getValueType(): string
* @param mixed $value
* @return string
*/
- public static function parseValueType($value): string
+ public static function parseValueType(mixed $value): string
{
if (is_array($value)) {
$value = Arrays::first($value);
@@ -103,9 +103,9 @@ public static function parseValueType($value): string
* Returns an array of all type strings.
*
* @param string $comment
- * @return string[]|null Null if missing/invalid.
+ * @return string[] empty if missing/invalid.
*/
- public static function parseCommentTypes(string $comment)
+ public static function parseCommentTypes(string $comment): array
{
if (!$comment) return [];
diff --git a/src/DocValidator.php b/src/DocValidator.php
index 6a446a0..9fbcfb9 100644
--- a/src/DocValidator.php
+++ b/src/DocValidator.php
@@ -6,8 +6,8 @@
namespace karmabunny\kb;
-use Exception;
use Generator;
+use karmabunny\interfaces\ValidatorInterface;
use ReflectionClass;
use ReflectionProperty;
@@ -29,7 +29,8 @@
* ```
* @package karmabunny\kb
*/
-class DocValidator implements Validator {
+class DocValidator implements ValidatorInterface
+{
/** @var object */
protected $target;
@@ -46,7 +47,7 @@ class DocValidator implements Validator {
*
* @param object $target Object to validate.
*/
- public function __construct($target)
+ public function __construct(object $target)
{
$this->target = $target;
$this->errors = [];
@@ -166,7 +167,7 @@ public function checkTypes(DocType $type): bool
* @param object $target
* @return Generator
*/
- public static function getDocTypes($target): Generator
+ public static function getDocTypes(object $target): Generator
{
$class = new ReflectionClass($target);
$properties = $class->getProperties(ReflectionProperty::IS_PUBLIC);
@@ -196,7 +197,7 @@ public static function getDocTypes($target): Generator
* @param mixed $value real value
* @return bool True if valid.
*/
- protected function isValid(string $expected, $value): bool
+ protected function isValid(string $expected, mixed $value): bool
{
if ($value === null and $expected === 'null') {
return true;
@@ -308,7 +309,7 @@ protected function isValidArray(string $expected, array $values): bool
* @param string $name
* @return string|null null if not found.
*/
- protected function lookupClass(string $name)
+ protected function lookupClass(string $name): ?string
{
if (!trim($name)) return null;
diff --git a/src/DocValidatorTrait.php b/src/DocValidatorTrait.php
index a71671c..89dc900 100644
--- a/src/DocValidatorTrait.php
+++ b/src/DocValidatorTrait.php
@@ -7,12 +7,14 @@
namespace karmabunny\kb;
use Exception;
+use karmabunny\interfaces\ValidatesInterface;
/**
* Use '@var' comments to validate object properties.
*
* @see DocValidator
*
+ * @mixin ValidatesInterface
* @package karmabunny\kb
*/
trait DocValidatorTrait {
@@ -28,7 +30,7 @@ trait DocValidatorTrait {
* @return void
* @throws ValidationException
*/
- public function validate(?string $scenario = null)
+ public function validate(?string $scenario = null): void
{
$errors = $this->valid($scenario);
if ($errors !== true) {
@@ -44,7 +46,7 @@ public function validate(?string $scenario = null)
* @return array|true True if valid, errors array if invalid.
* @throws Exception
*/
- public function valid(?string $scenario = null)
+ public function valid(?string $scenario = null): array|true
{
$valid = new DocValidator($this);
if (!$valid->validate()) {
diff --git a/src/Enc.php b/src/Enc.php
index cceb067..7fd27bc 100644
--- a/src/Enc.php
+++ b/src/Enc.php
@@ -20,11 +20,11 @@ class Enc
* Funky stuff is anything in the ASCII control plane (0x00 - 0x1F)
* Except tab, line feed, carriage return
**/
- public static function cleanfunky($value)
+ public static function cleanfunky(mixed $value): string
{
if (is_array($value)) return '';
if (is_object($value)) return '';
- return preg_replace('![\x00-\x08\x0B\x0C\x0E-\x1F]!', '', (string) $value);
+ return preg_replace('![\x00-\x08\x0B\x0C\x0E-\x1F]!', '', (string) $value) ?: '';
}
/**
@@ -35,7 +35,7 @@ public static function cleanfunky($value)
* @example $html = Enc::html('A & B'); // returns A & B
* @example $bad_html = Enc::html('A & B'); // don't do this; returns A & B
*/
- public static function html($value)
+ public static function html(mixed $value): string
{
return htmlspecialchars(self::cleanfunky($value), ENT_COMPAT, 'UTF-8');
}
@@ -47,9 +47,9 @@ public static function html($value)
* @example $html = Enc::html('A & B'); // returns A & B
* @example $html = Enc::html('A & B'); // this is fine; returns A & B
*/
- public static function htmlNoDup($value)
+ public static function htmlNoDup(mixed $value): string
{
- return htmlspecialchars(self::cleanfunky($value), ENT_COMPAT, 'UTF-8', false);
+ return htmlspecialchars(self::cleanfunky($value), ENT_COMPAT, 'UTF-8', false) ?: '';
}
/**
@@ -57,7 +57,7 @@ public static function htmlNoDup($value)
*
* @param string $value The value to encode
**/
- public static function xml($value)
+ public static function xml(mixed $value): string
{
$value = self::cleanfunky($value);
$value = preg_replace('/[\s\r\n][\s\r\n]+/', "\n", $value);
@@ -69,7 +69,7 @@ public static function xml($value)
*
* @param string $value The value to encode
**/
- public static function url($value)
+ public static function url(mixed $value): string
{
return urlencode(self::cleanfunky($value));
}
@@ -79,7 +79,7 @@ public static function url($value)
*
* @param string $value The value to encode
**/
- public static function id($value)
+ public static function id(mixed $value): string
{
$value = self::cleanfunky($value);
$value = trim($value);
@@ -112,7 +112,7 @@ public static function js($value)
*
* @param string $value The value to encode
**/
- public static function httpfield($value)
+ public static function httpfield(mixed $value): string
{
$value = self::cleanfunky($value);
$value = str_replace(' ', '_', $value);
@@ -131,7 +131,7 @@ public static function httpfield($value)
* @param string $value The value to encode
* @return string
*/
- public static function urlname($value, $delimiter = '-')
+ public static function urlname(mixed $value, string $delimiter = '-'): string
{
$value = self::cleanfunky($value);
$value = strtolower(trim($value, "&_- \t\n\r\0\x0B"));
@@ -162,7 +162,7 @@ public static function urlname($value, $delimiter = '-')
* @param string $from What format the date was in origanally.
* @return string|null JavaScript snippet for the given date or NULL if the input value is invalid
**/
- public static function jsdate($value, $from = 'mysql')
+ public static function jsdate(mixed $value, string $from = 'mysql'): ?string
{
$day = null;
$month = null;
diff --git a/src/Encrypt.php b/src/Encrypt.php
index 2d42fbd..55c4562 100644
--- a/src/Encrypt.php
+++ b/src/Encrypt.php
@@ -16,7 +16,7 @@ class Encrypt implements EncryptInterface
{
/** @var array */
- protected $config;
+ protected array $config;
/**
diff --git a/src/Env.php b/src/Env.php
index 6c77665..5744df8 100644
--- a/src/Env.php
+++ b/src/Env.php
@@ -34,13 +34,13 @@ class Env
];
/** The key name to determine the current environment mode. */
- static $ENV_NAME = 'SITES_ENVIRONMENT';
+ public static string $ENV_NAME = 'SITES_ENVIRONMENT';
/** The default environment, default 'DEV'. */
- static $DEFAULT = self::DEV;
+ public static string $DEFAULT = self::DEV;
/** @var string[]|null */
- static $config;
+ public static ?array $config = null;
/**
@@ -52,7 +52,7 @@ class Env
* @param array $config (ENV_NAME, DEFAULT)
* @return void
*/
- public static function config(array $config)
+ public static function config(array $config): void
{
self::$ENV_NAME = $config['ENV_NAME'] ?? self::$ENV_NAME;
self::$DEFAULT = $config['DEFAULT'] ?? self::$DEFAULT;
@@ -148,7 +148,7 @@ protected static function load(): array
* @param string $key
* @return string|null
*/
- public static function get(string $key)
+ public static function get(string $key): ?string
{
$config = self::load();
return $config[$key] ?? null;
diff --git a/src/Event.php b/src/Event.php
index ee72881..98db447 100644
--- a/src/Event.php
+++ b/src/Event.php
@@ -17,9 +17,9 @@ abstract class Event extends DataObject implements EventInterface
{
/** @var object|null */
- public $sender;
+ public ?object $sender = null;
/** @var bool */
- public $handled = false;
+ public bool $handled = false;
}
diff --git a/src/EventableTrait.php b/src/EventableTrait.php
index dde2c43..1b14259 100644
--- a/src/EventableTrait.php
+++ b/src/EventableTrait.php
@@ -72,12 +72,12 @@ protected function trigger(?string $class, EventInterface $event, bool $once = f
*
* @see Events::on()
* @param class-string|callable $event
- * @param callable|bool|null $fn
+ * @param callable|null $fn
* @param bool $append
* @return void
* @throws InvalidArgumentException
*/
- public function on($event, $fn = null, bool $append = true)
+ public function on(string|callable $event, ?callable $fn = null, bool $append = true): void
{
// Unlike trigger, using dynamic class names here is OK. A user is not
// surprised (hopefully) that they only receive events appropriate for
@@ -94,7 +94,7 @@ public function on($event, $fn = null, bool $append = true)
* @param class-string|null $event
* @return void
*/
- public function off($event)
+ public function off(?string $event = null): void
{
Events::off($this, $event);
}
diff --git a/src/Events.php b/src/Events.php
index 335cd35..1275b4f 100644
--- a/src/Events.php
+++ b/src/Events.php
@@ -1,4 +1,5 @@
|callable $event
- * @param callable|bool|null $fn
+ * @param callable|null $fn
* @param bool $append
* @return void
* @throws InvalidArgumentException
*/
- public static function on($sender, $event, $fn = null, bool $append = true)
+ public static function on(string|object $sender, string|callable $event, ?callable $fn = null, bool $append = true): void
{
- // If no handler is given, assume the second parameter is handler.
// Using some cheeky reflection we can extract the event type.
- if ($fn === null or is_bool($fn)) {
- $append = $fn ?? $append;
-
+ if ($fn === null) {
try {
$fn = $event;
$event = null;
@@ -235,7 +233,7 @@ public static function on($sender, $event, $fn = null, bool $append = true)
* @param class-string|null $event
* @return void
*/
- public static function off($sender, ?string $event = null)
+ public static function off(string|object|null $sender, ?string $event = null): void
{
if (is_object($sender)) {
$sender = get_class($sender);
@@ -349,7 +347,7 @@ public static function hasRun(string $sender, string $event): bool
* @param bool $logging
* @return void
*/
- public static function setLogging(bool $logging)
+ public static function setLogging(bool $logging): void
{
self::$_log = $logging ? [] : null;
}
@@ -361,7 +359,7 @@ public static function setLogging(bool $logging)
* @param bool $clearRunLog
* @return void
*/
- public static function clearLog(bool $clearRunLog = false)
+ public static function clearLog(bool $clearRunLog = false): void
{
if (self::$_log !== null) {
self::$_log = [];
diff --git a/src/Generate.php b/src/Generate.php
index ecb0f13..b179b74 100644
--- a/src/Generate.php
+++ b/src/Generate.php
@@ -15,16 +15,16 @@ class Generate
{
/** @var string */
- public $indent = ' ';
+ public string $indent = ' ';
/** @var resource */
- protected $stream;
+ protected mixed $stream;
/** @var bool */
- protected $close;
+ protected bool $close;
/** @var int */
- protected $depth = 1;
+ protected int $depth = 1;
/**
@@ -32,7 +32,7 @@ class Generate
* @param string|resource $target
* @return void
*/
- public function __construct($target)
+ public function __construct(mixed $target)
{
if (is_string($target)) {
$this->stream = fopen($target, 'w');
@@ -51,7 +51,7 @@ public function __construct($target)
*
* @return void
*/
- public function close()
+ public function close(): void
{
if ($this->close) {
@fflush($this->stream);
@@ -74,7 +74,7 @@ public function __destruct()
* @param string $comment
* @return void
*/
- public function comment(string $comment)
+ public function comment(string $comment): void
{
fwrite($this->stream, "// {$comment}\n");
}
@@ -85,7 +85,7 @@ public function comment(string $comment)
* @param array $array
* @return void
*/
- public function write(array $array)
+ public function write(array $array): void
{
fwrite($this->stream, "return [\n");
@@ -103,7 +103,7 @@ public function write(array $array)
* @param mixed $value
* @return void
*/
- protected function writeItem($key, $value)
+ protected function writeItem(string|int|null $key, mixed $value): void
{
if ($key !== null and !is_int($key)) {
$key = "'{$key}'";
diff --git a/src/HttpStatus.php b/src/HttpStatus.php
index 43f0880..42e76a4 100644
--- a/src/HttpStatus.php
+++ b/src/HttpStatus.php
@@ -167,6 +167,8 @@ class HttpStatus
/**
* Status code strings.
+ *
+ * @var array
*/
const STRINGS = [
self::CONTINUE => 'Continue',
diff --git a/src/Inflector.php b/src/Inflector.php
index 9baef63..dabff1d 100644
--- a/src/Inflector.php
+++ b/src/Inflector.php
@@ -23,12 +23,13 @@
class Inflector extends DataObject implements InflectorInterface
{
- // Cached inflections
- protected $_cache = [];
+ protected array $_cache = [];
- // Uncountable and irregular words
- public $uncountable = [];
- public $irregular = [];
+ /** @var string[] */
+ public array $uncountable = [];
+
+ /** @var array */
+ public array $irregular = [];
/** @inheritdoc */
@@ -43,7 +44,7 @@ public function __construct($config = null)
/** @inheritdoc */
- public function update($config)
+ public function update(iterable $config): void
{
parent::update($config);
$this->uncountable = array_combine($this->uncountable, $this->uncountable);
@@ -70,7 +71,7 @@ public function uncountable(string $word): bool
* @param int $count number of things
* @return string
*/
- public function singular($word, $count = 1): string
+ public function singular(string $word, int $count = 1): string
{
$key = "singular_{$word}_{$count}";
@@ -93,7 +94,7 @@ public function singular($word, $count = 1): string
* @param int $count
* @return string
*/
- public function plural($word, $count = 0): string
+ public function plural(string $word, int $count = 0): string
{
$key = "singular_{$word}_{$count}";
@@ -116,7 +117,7 @@ public function plural($word, $count = 0): string
* @param int $count number of things
* @return string
*/
- protected function _singular($word, $count = 1)
+ protected function _singular(string $word, int $count = 1): string
{
// Remove garbage
$word = strtolower(trim($word));
@@ -163,7 +164,7 @@ protected function _singular($word, $count = 1)
* @param int $count
* @return string
*/
- protected function _plural($word, $count = 0)
+ protected function _plural(string $word, int $count = 0): string
{
// Remove garbage
$word = strtolower(trim($word));
@@ -205,7 +206,7 @@ protected function _plural($word, $count = 0)
* @param bool $first Upper case the first letter
* @return string
*/
- public static function camelize($phrase, $first = true)
+ public static function camelize(string $phrase, bool $first = true): string
{
$phrase = self::humanize($phrase);
$phrase = ucwords(preg_replace('/\s+/', ' ', $phrase));
@@ -225,7 +226,7 @@ public static function camelize($phrase, $first = true)
* @param string $phrase
* @return string
*/
- public static function underscore($phrase)
+ public static function underscore(string $phrase): string
{
$phrase = self::humanize($phrase);
return preg_replace('/\s+/', '_', trim($phrase));
@@ -238,7 +239,7 @@ public static function underscore($phrase)
* @param string $phrase
* @return string
*/
- public static function kebab($phrase)
+ public static function kebab(string $phrase): string
{
$phrase = self::humanize($phrase);
return preg_replace('/\s+/', '-', trim($phrase));
@@ -251,7 +252,7 @@ public static function kebab($phrase)
* @param string $phrase
* @return string
*/
- public static function humanize($phrase)
+ public static function humanize(string $phrase): string
{
// Convert from underscore + kebab.
$phrase = trim(preg_replace('/[\s_-]+/', ' ', $phrase));
diff --git a/src/Job.php b/src/Job.php
index 0326da6..bae1d24 100644
--- a/src/Job.php
+++ b/src/Job.php
@@ -29,31 +29,35 @@ abstract class Job implements
use RulesValidatorTrait;
/** @var string */
- public $id;
+ public string $id = '';
/** @var int Unix timestamp in seconds. */
- public $start;
+ public int $start = 0;
/** @var array */
- public $config;
+ public array $config = [];
/**
* Create and validate a job with this config.
*
* @param array $config
+ * @param bool $validate
* @return void
*/
- public function __construct(array $config)
+ public function __construct(array $config = [], bool $validate = true)
{
$this->update($config);
$this->start = time();
- $this->validate();
+
+ if ($config and $validate) {
+ $this->validate();
+ }
}
/** @inheritdoc */
- public function update($config)
+ public function update(iterable $config): void
{
if (!is_array($config)) {
$config = iterator_to_array($config, true);
@@ -84,6 +88,13 @@ public function getValidator(): RulesValidatorInterface
}
+ /** @inheritdoc */
+ public function rules(?string $scenario = null): array
+ {
+ return [];
+ }
+
+
/**
* Get the current stats.
*
@@ -111,13 +122,14 @@ public function stats(): array
* Shorthand for creating, validating and running a job.
*
* @param array $config
- * @return Job
+ * @return static
*/
- public static function execute(array $config = [])
+ public static function execute(array $config = []): static
{
- $class = static::class;
-
- $job = new $class($config);
+ // @phpstan-ignore-next-line
+ $job = new static();
+ $job->update($config);
+ $job->validate();
$job->addLogger(function($message) {
echo Log::stringify($message), PHP_EOL;
diff --git a/src/Json.php b/src/Json.php
index a576aed..540bd01 100644
--- a/src/Json.php
+++ b/src/Json.php
@@ -1,4 +1,5 @@
attach($parent, null, ['stats' => false, 'meta' => false]);
* ```
*
- * @param callable|Loggable $logger
+ * @param callable|LogSinkInterface $logger
* @param int|null $level
* @param string|array|null $category
* @return callable
*/
- public static function filter($logger, $level = null, $category = null)
+ public static function filter(callable|LogSinkInterface $logger, ?int $level = null, string|array|null $category = null): callable
{
if ($level === null and $category === null) {
return $logger;
@@ -177,7 +177,7 @@ public static function filter($logger, $level = null, $category = null)
* @param int $timestamp
* @return void - echoes to stdout
*/
- public static function print($message, $level, $category, $timestamp)
+ public static function print(mixed $message, int $level, string $category, int $timestamp): void
{
echo self::format($message, $level, $category, $timestamp);
}
@@ -191,7 +191,7 @@ public static function print($message, $level, $category, $timestamp)
* @param int $timestamp
* @return string
*/
- public static function format($message, $level, $category, $timestamp)
+ public static function format(mixed $message, int $level, string $category, int $timestamp): string
{
$line = '';
$line .= '[' . date('c', $timestamp) . ']';
@@ -206,9 +206,10 @@ public static function format($message, $level, $category, $timestamp)
* An attempt to convert things into strings.
*
* @param mixed $value
+ * @param int $indent
* @return string
*/
- public static function stringify($value, $indent = 0): string
+ public static function stringify(mixed $value, int $indent = 0): string
{
// Bad hack.
if (!$indent and is_object($value)) $indent = 2;
@@ -290,7 +291,7 @@ public static function stringify($value, $indent = 0): string
* @param mixed $thing
* @return void
*/
- public static function dump($thing)
+ public static function dump(mixed $thing): void
{
while (ob_get_level() > 0) ob_end_clean();
header('content-type: text/plain');
@@ -310,7 +311,7 @@ public static function dump($thing)
* @param int[]|int $levels Filtering; only log on these levels
* @return callable (message, level, category)
*/
- public static function createFileLogger(string $path, $cache_size = 5, $levels = null)
+ public static function createFileLogger(string $path, int $cache_size = 5, int|array|null $levels = null): callable
{
// A happy little closure value.
$cache = [];
diff --git a/src/LoggerTrait.php b/src/LoggerTrait.php
index 10762a5..b5b68e3 100644
--- a/src/LoggerTrait.php
+++ b/src/LoggerTrait.php
@@ -20,7 +20,7 @@ trait LoggerTrait {
private $loggers = [];
- public function clearLoggers()
+ public function clearLoggers(): void
{
$this->loggers = [];
}
@@ -47,15 +47,15 @@ public function clearLoggers()
* ```
*
* @param callable|LogSinkInterface $logger (message, level, category, timestamp)
- * @param string|array|null $category filter by category
* @param int|null $level filter by level
+ * @param string|array|null $category filter by category
* @return int
*/
- public function addLogger($logger, ?int $level = null, $category = null): int
+ public function addLogger(callable|LogSinkInterface $logger, ?int $level = null, string|array|null $category = null): int
{
if (
$logger === $this
- or (is_array($logger) and ($logger[0] ?? false) === $this)
+ or (is_array($logger) and ($logger[0]) === $this)
) {
throw new InvalidArgumentException('Cannot attach to self');
}
@@ -78,11 +78,11 @@ public function addLogger($logger, ?int $level = null, $category = null): int
*
* @deprecated Use addLogger() instead
* @param callable|LogSinkInterface $logger
- * @param string|array|null $category filter by category
* @param int|null $level filter by level
+ * @param string|array|null $category filter by category
* @return void
*/
- public function attach($logger, ?int $level = null, $category = null)
+ public function attach(callable|LogSinkInterface $logger, ?int $level = null, string|array|null $category = null): void
{
$this->addLogger($logger, $level, $category);
}
@@ -93,18 +93,18 @@ public function attach($logger, ?int $level = null, $category = null)
*
* @param mixed $message
* @param int $level default: LEVEL_INFO
- * @param string|null $_category default: class name (static)
- * @param int|float|null $_timestamp default: now
+ * @param string|null $category default: class name (static)
+ * @param float|null $timestamp default: now
* @return void
*/
- public function log($message, ?int $level = null, ?string $_category = null, $_timestamp = null)
+ public function log(mixed $message, ?int $level = null, ?string $category = null, ?float $timestamp = null): void
{
if ($level === null) $level = Log::LEVEL_INFO;
- if ($_category === null) $_category = static::class;
- if ($_timestamp === null) $_timestamp = microtime(true);
+ if ($category === null) $category = static::class;
+ if ($timestamp === null) $timestamp = microtime(true);
foreach ($this->loggers as $logger) {
- $logger($message, $level, $_category, $_timestamp);
+ $logger($message, $level, $category, $timestamp);
}
}
}
diff --git a/src/PropertiesTrait.php b/src/PropertiesTrait.php
index 43b65e5..9af124a 100644
--- a/src/PropertiesTrait.php
+++ b/src/PropertiesTrait.php
@@ -7,6 +7,7 @@
namespace karmabunny\kb;
use ReflectionClass;
+use ReflectionNamedType;
use ReflectionProperty;
/**
@@ -75,8 +76,8 @@ public static function getPropertyDefaults(): array
/**
* Get a list of properties, with respective types (if available).
*
- * Beginning with PHP 7.4 object properties can have strict types. If not
- * typed or running a older PHP all properties will be `mixed`.
+ * Object properties can have strict types. If not typed, all properties
+ * will be `mixed`.
*
* @return string[] [ name => type ]
*/
@@ -95,17 +96,14 @@ public static function getPropertyTypes(): array
if ($property->isStatic()) continue;
$name = $property->getName();
- $type = null;
-
- if (PHP_VERSION_ID >= 74000) {
- // @phpstan-ignore-next-line
- $type = $property->getType();
- if ($type !== null) {
- $type = $type->getName();
- }
+ $type_name = null;
+
+ $type = $property->getType();
+ if ($type instanceof ReflectionNamedType) {
+ $type_name = $type->getName();
}
- $fields[$name] = $type ?? 'mixed';
+ $fields[$name] = $type_name ?? 'mixed';
}
$_FIELDS[static::class] = $fields;
diff --git a/src/Reflect.php b/src/Reflect.php
index b0ca653..1f73751 100644
--- a/src/Reflect.php
+++ b/src/Reflect.php
@@ -1,4 +1,5 @@
setAccessible(true);
- // @phpstan-ignore-next-line : PHP 7.4+
- if (PHP_VERSION_ID >= 70400 and !$property->isInitialized($target)) {
+ if (!$property->isInitialized($target)) {
// Don't serialize uninitialized properties
continue;
}
- else {
- // We need to use getValue() so to bypass any __get() magic.
- $value = $property->getValue($target);
- }
+
+ // We need to use getValue() so to bypass any __get() magic.
+ $value = $property->getValue($target);
$key = $property->getName();
$data[$key] = $value;
@@ -226,9 +224,10 @@ public static function getMethods(string $class, ?string $filter = null): array
/**
*
* @param ReflectionFunctionAbstract|string[]|string $function
+ * @param string[]|null $fallbacks
* @return array
*/
- public static function getParameters($function, ?array $fallbacks = null): array
+ public static function getParameters(ReflectionFunctionAbstract|array|string $function, ?array $fallbacks = null): array
{
if (is_array($function)) {
list($class, $method) = $function;
@@ -268,7 +267,7 @@ public static function getParameters($function, ?array $fallbacks = null): array
* @param string|null $fallback
* @return string
*/
- public static function getTypeName($type, ?string $fallback = null): string
+ public static function getTypeName(?ReflectionType $type, ?string $fallback = null): string
{
if ($type instanceof ReflectionNamedType) {
$type = $type->getName();
diff --git a/src/RulesClassValidator.php b/src/RulesClassValidator.php
index 0ed62a0..88f9cc9 100644
--- a/src/RulesClassValidator.php
+++ b/src/RulesClassValidator.php
@@ -24,37 +24,37 @@ class RulesClassValidator implements RulesValidatorInterface
{
/** @var array|object */
- protected $data;
+ protected array|object $data;
/**
* Available rules, as installed by setValidators().
*
* @var RuleInterface[]
*/
- protected $validators = [];
+ protected array $validators = [];
/**
* Active rules, a subset of the validators as determined by setRules().
*
* @var RuleInterface[]
*/
- protected $rules = [];
+ protected array $rules = [];
/**
* A copy of the original rulesets, used for reparsing rules.
*
* @var array
*/
- protected $original_rules = [];
+ protected array $original_rules = [];
/** @var array */
- protected $errors = [];
+ protected array $errors = [];
/**
* @param array|object $data Data to validate
*/
- public function __construct($data)
+ public function __construct(array|object $data)
{
$validators = require __DIR__ . '/config/rules.php';
$this->setValidators($validators);
@@ -67,7 +67,7 @@ public function __construct($data)
*
* @param array|object $data Data to validate
*/
- public function setData($data)
+ public function setData(array|object $data): void
{
if (is_array($data) or $data instanceof ArrayAccess) {
$this->data = $data;
@@ -86,7 +86,7 @@ public function setData($data)
* @param string $field The field to set
* @param mixed $value The value to set on the field
*/
- public function setFieldValue($field, $value)
+ public function setFieldValue(string $field, mixed $value): void
{
$this->data[$field] = $value;
}
@@ -98,7 +98,7 @@ public function setFieldValue($field, $value)
* @return void
* @throws InvalidArgumentException
*/
- public function setValidators(array $validators)
+ public function setValidators(array $validators): void
{
$this->validators = [];
@@ -125,7 +125,7 @@ public function setValidators(array $validators)
* @return void
* @throws InvalidArgumentException
*/
- public function addValidator($validator, ?string $name = null)
+ public function addValidator($validator, ?string $name = null): void
{
/** @var RuleInterface $validator */
$validator = Configure::configure($validator, RuleInterface::class);
@@ -182,14 +182,14 @@ public function parseRule(string $name, array $ruleset): RuleInterface
* @return void
* @throws InvalidArgumentException
*/
- public function refreshRules()
+ public function refreshRules(): void
{
$this->setRules($this->original_rules);
}
/** @inheritdoc */
- public function setRules(array $rules)
+ public function setRules(array $rules): void
{
$this->original_rules = $rules;
@@ -307,7 +307,7 @@ public function validate(): bool
*
* @param array $fields Fields to check
*/
- public function required(array $fields)
+ public function required(array $fields): void
{
foreach ($fields as $field_name) {
if (RequiredRule::isEmpty($this->data, $field_name)) {
@@ -323,7 +323,7 @@ public function required(array $fields)
* @param string $field_name The field to add the error message for
* @param string|string[] $message The message text
*/
- public function addFieldError($field_name, $message)
+ public function addFieldError(string $field_name, string|array $message): void
{
if (is_array($message)) {
foreach ($message as $item) {
@@ -342,7 +342,7 @@ public function addFieldError($field_name, $message)
* @param array $fields The fields to add the error message for
* @param string $message The message text
*/
- public function addMultipleFieldError(array $fields, $message)
+ public function addMultipleFieldError(array $fields, string $message): void
{
foreach ($fields as $f) {
$this->addFieldError($f, $message);
diff --git a/src/RulesStaticValidator.php b/src/RulesStaticValidator.php
index 3761667..1ba7b22 100644
--- a/src/RulesStaticValidator.php
+++ b/src/RulesStaticValidator.php
@@ -79,12 +79,12 @@
*/
class RulesStaticValidator implements RulesValidatorInterface
{
- protected $labels;
- protected $data;
- protected $rules;
- protected $field_errors;
- protected $general_errors;
- protected $validity;
+ protected array $labels;
+ protected array|object $data;
+ protected array $rules;
+ protected array $field_errors;
+ protected array $general_errors;
+ protected string $validity;
/**
* Recursive trim data
@@ -118,7 +118,7 @@ public static function trim(array &$data)
* @param array|object $data Data to validate
* @param array $rules Validation rules
*/
- public function __construct($data, array $rules = [])
+ public function __construct(array|object $data, array $rules = [])
{
$this->labels = [];
$this->field_errors = [];
@@ -135,7 +135,7 @@ public function __construct($data, array $rules = [])
*
* @param array $labels Field labels
*/
- public function setLabels(array $labels)
+ public function setLabels(array $labels): void
{
$this->labels = $labels;
}
@@ -146,7 +146,7 @@ public function setLabels(array $labels)
*
* @param array|object $data Data to validate
*/
- public function setData($data)
+ public function setData(array|object $data): void
{
if (is_array($data) or $data instanceof ArrayAccess) {
$this->data = $data;
@@ -164,7 +164,7 @@ public function setData($data)
* @param array $rules
* @return void
*/
- public function setRules(array $rules)
+ public function setRules(array $rules): void
{
$this->rules = $rules;
}
@@ -176,7 +176,7 @@ public function setRules(array $rules)
* @param string $field The field to set
* @param mixed $value The value to set on the field
*/
- public function setFieldValue($field, $value)
+ public function setFieldValue(string $field, mixed $value): void
{
$this->data[$field] = $value;
}
@@ -188,7 +188,7 @@ public function setFieldValue($field, $value)
* @param string $field The field to set
* @param string $label The label to set on the field
*/
- public function setFieldLabel($field, $label)
+ public function setFieldLabel(string $field, string $label): void
{
$this->labels[$field] = $label;
}
@@ -200,7 +200,7 @@ public function setFieldLabel($field, $label)
* @param string $class
* @throws InvalidArgumentException
*/
- public function setValidity(string $class)
+ public function setValidity(string $class): void
{
if (!class_exists($class)) {
throw new InvalidArgumentException("Invalid validity class: {$class}");
@@ -215,7 +215,7 @@ public function setValidity(string $class)
* @param callable|string $func The function to expand.
* @return callable|false False if not callable.
*/
- protected function expandNs($func)
+ protected function expandNs(callable|string $func): mixed
{
// Check for methods on a validity class first.
$expanded = [$this->validity, $func];
@@ -351,11 +351,11 @@ public function validate(): bool
* If a empty value is provided, it is not validated - returns true
*
* @param string $field_name The field to check
- * @param callable $func The function or method to call.
+ * @param callable|string $func The function or method to call.
* @param array $args
* @return bool True if validation was successful, false if it failed
*/
- public function check($field_name, $func, ...$args)
+ public function check(string $field_name, callable|string $func, mixed ...$args): bool
{
$value = $this->data[$field_name] ?? null;
@@ -394,11 +394,11 @@ public function check($field_name, $func, ...$args)
* // $errs now contains [ 'vals' => [2 => [...], 3 => [...]] ]
*
* @param string $field_name The field to check
- * @param callable $func The function or method to call.
+ * @param callable|string $func The function or method to call.
* @param array $args
* @return array Key => Boolean True if validation was successful, false if it failed
*/
- public function arrayCheck($field_name, $func, ...$args)
+ public function arrayCheck(string $field_name, callable|string $func, mixed ...$args): array
{
$values = $this->data[$field_name] ?? null;
@@ -436,11 +436,11 @@ public function arrayCheck($field_name, $func, ...$args)
* Additional arguments are passed to the underlying method
*
* @param array $fields The fields to check
- * @param callable $func The function or method to call.
+ * @param callable|string $func The function or method to call.
* @param array $args
* @return bool True if validation was successful, false if it failed
*/
- public function multipleCheck(array $fields, $func, ...$args)
+ public function multipleCheck(array $fields, callable|string $func, mixed ...$args): bool
{
$this->expandNs($func);
@@ -466,7 +466,7 @@ public function multipleCheck(array $fields, $func, ...$args)
* @param mixed $val
* @return bool True if empty, false if not.
*/
- public static function isEmpty($val)
+ public static function isEmpty($val): bool
{
if (is_array($val) and count($val) == 0) {
return true;
@@ -483,7 +483,7 @@ public static function isEmpty($val)
*
* @param array $fields Fields to check
*/
- public function required(array $fields)
+ public function required(array $fields): void
{
foreach ($fields as $field_name) {
if (!isset($this->data[$field_name])) {
@@ -501,7 +501,7 @@ public function required(array $fields)
* @param string $field_name The field to add the error message for
* @param string $message The message text
*/
- public function addFieldError($field_name, $message)
+ public function addFieldError(string $field_name, string $message): void
{
if (!isset($this->field_errors[$field_name])) {
$this->field_errors[$field_name] = [$message];
@@ -519,7 +519,7 @@ public function addFieldError($field_name, $message)
* @param int $index The array index of the field to report error for
* @param string $message The message text
*/
- public function addArrayFieldError($field_name, $index, $message)
+ public function addArrayFieldError(string $field_name, int $index, string $message): void
{
if (!isset($this->field_errors[$field_name])) {
$this->field_errors[$field_name] = [];
@@ -538,7 +538,7 @@ public function addArrayFieldError($field_name, $index, $message)
* @param array $fields The fields to add the error message for
* @param string $message The message text
*/
- public function addMultipleFieldError(array $fields, $message)
+ public function addMultipleFieldError(array $fields, string $message): void
{
foreach ($fields as $f) {
$this->addFieldError($f, $message);
@@ -552,7 +552,7 @@ public function addMultipleFieldError(array $fields, $message)
*
* @return array
*/
- public function getFieldErrors()
+ public function getFieldErrors(): array
{
return $this->field_errors;
}
@@ -576,7 +576,7 @@ public function getErrors(): array
*
* @param string $message The message text
*/
- public function addGeneralError($message)
+ public function addGeneralError(string $message): void
{
$this->general_errors[] = $message;
}
@@ -587,7 +587,7 @@ public function addGeneralError($message)
*
* @return array
*/
- public function getGeneralErrors()
+ public function getGeneralErrors(): array
{
return $this->general_errors;
}
diff --git a/src/RulesValidatorTrait.php b/src/RulesValidatorTrait.php
index e51d141..a9ff74d 100644
--- a/src/RulesValidatorTrait.php
+++ b/src/RulesValidatorTrait.php
@@ -8,6 +8,7 @@
use Exception;
use karmabunny\interfaces\RulesValidatorInterface;
+use karmabunny\interfaces\ValidatesInterface;
/**
* Use validator functions to validate properties.
@@ -16,6 +17,7 @@
* @see RulesClassValidator
* @see Validity
*
+ * @mixin ValidatesInterface
* @package karmabunny\kb
*/
trait RulesValidatorTrait
@@ -102,7 +104,7 @@ public function getValidator(): RulesValidatorInterface
* @throws Exception
* @throws ValidationException
*/
- public function validate(?string $scenario = null)
+ public function validate(?string $scenario = null): void
{
$errors = $this->valid($scenario);
if ($errors !== true) {
@@ -118,7 +120,7 @@ public function validate(?string $scenario = null)
* @return array|true True if valid, errors array if invalid.
* @throws Exception
*/
- public function valid(?string $scenario = null)
+ public function valid(?string $scenario = null): array|true
{
$valid = $this->getValidator();
diff --git a/src/Secrets.php b/src/Secrets.php
index 28efd42..0d769d5 100644
--- a/src/Secrets.php
+++ b/src/Secrets.php
@@ -74,16 +74,16 @@ class Secrets extends DataObject
/** @var string[] */
- public $key_rules;
+ public array $key_rules;
/** @var string[] */
- public $value_rules;
+ public array $value_rules;
/** @var string */
- public $key_pattern;
+ public string $key_pattern;
/** @var string */
- public $value_pattern;
+ public string $value_pattern;
/**
* Whether to treat _all_ base64 strings as secrets.
@@ -97,7 +97,7 @@ class Secrets extends DataObject
*
* @var bool
*/
- public $base64 = false;
+ public bool $base64 = false;
/**
* Whether to treat _all_ hex strings as secrets.
@@ -111,14 +111,14 @@ class Secrets extends DataObject
*
* @var bool
*/
- public $hex = false;
+ public bool $hex = false;
/**
* Create masks with fixed sizes.
*
* @var int|null
*/
- public $mask_length = 16;
+ public ?int $mask_length = 16;
/**
@@ -136,7 +136,7 @@ public static function create(array $config = [])
/** @inheritdoc */
- public function update($config)
+ public function update(iterable $config): void
{
parent::update($config);
$this->key_pattern = $this->buildPattern($this->key_rules);
@@ -150,7 +150,7 @@ public function update($config)
* @param string $pattern regex
* @return void
*/
- public function addKeyRule(string $pattern)
+ public function addKeyRule(string $pattern): void
{
$this->key_rules[] = $pattern;
$this->key_pattern = $this->buildPattern($this->key_rules);
@@ -163,7 +163,7 @@ public function addKeyRule(string $pattern)
* @param string $pattern regex
* @return void
*/
- public function addValueRule(string $pattern)
+ public function addValueRule(string $pattern): void
{
$this->value_rules[] = $pattern;
$this->value_pattern = static::buildPattern($this->value_rules);
@@ -176,7 +176,7 @@ public function addValueRule(string $pattern)
* @param mixed $item
* @return bool
*/
- public function isSecretKey($item): bool
+ public function isSecretKey(mixed $item): bool
{
if (!is_string($item)) {
return false;
@@ -201,7 +201,7 @@ public function isSecretKey($item): bool
* @param bool $recursive - process url/json strings
* @return bool
*/
- public function isSecretValue($item, bool $recursive = true): bool
+ public function isSecretValue(mixed $item, bool $recursive = true): bool
{
if (!is_string($item)) {
return false;
@@ -317,7 +317,7 @@ public function isSecretValue($item, bool $recursive = true): bool
* @param mixed $item
* @return bool
*/
- public function isSecret($item): bool
+ public function isSecret(mixed $item): bool
{
if (!is_string($item)) {
return false;
diff --git a/src/Security.php b/src/Security.php
index 459332c..a5464ba 100644
--- a/src/Security.php
+++ b/src/Security.php
@@ -37,7 +37,7 @@ class Security
* @param int $length
* @return string Binary string
*/
- public static function randBytes($length)
+ public static function randBytes(int $length): string
{
$length = (int) $length;
if ($length < 8) {
@@ -53,7 +53,7 @@ public static function randBytes($length)
*
* @return string Binary string; one byte
*/
- public static function randByte()
+ public static function randByte(): string
{
static $buffer = [];
if (count($buffer) === 0) {
@@ -69,7 +69,7 @@ public static function randByte()
* @param int $length
* @return string
*/
- public static function randStr($length = 16, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890')
+ public static function randStr(int $length = 16, string $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'): string
{
$num_chars = strlen($chars) * 1.0;
$mask = 256 - (256 % $num_chars);
@@ -95,7 +95,7 @@ public static function randStr($length = 16, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXY
* @param string $user_string The user supplied hash to check
* @return bool True if the strings match, false if they don't
*/
- public static function compareStrings($known_string, $user_string)
+ public static function compareStrings(string $known_string, string $user_string): bool
{
return hash_equals($known_string, $user_string);
}
@@ -106,12 +106,12 @@ public static function compareStrings($known_string, $user_string)
*
* @deprecated Use password_hash() instead.
* @param string $known_hash The known hash to check against, typically from the database
- * @param int $algorithm Password algorithm, {@see self}
+ * @param int|string $algorithm Password algorithm, {@see self}
* @param string $salt
* @param string $user_string Password which was entered by the user, to check against the stored hash
* @return bool True if the password matches, false if it doesn't
*/
- public static function doPasswordCheck($known_hash, $algorithm, $salt, $user_string)
+ public static function doPasswordCheck(string $known_hash, int|string $algorithm, string $salt, string $user_string): bool
{
switch ($algorithm) {
case self::PASSWORD_DEFAULT:
@@ -152,7 +152,7 @@ public static function doPasswordCheck($known_hash, $algorithm, $salt, $user_str
* @return array 0 => hash, 1 => algorithm, 2 => salt
* @throws InvalidArgumentException
*/
- public static function hashPassword($password, $algorithm = self::PASSWORD_DEFAULT)
+ public static function hashPassword(string $password, int|string $algorithm = self::PASSWORD_DEFAULT): array
{
switch ($algorithm) {
case self::PASSWORD_DEFAULT:
diff --git a/src/SerializeTrait.php b/src/SerializeTrait.php
index cc2c2fc..78957c9 100644
--- a/src/SerializeTrait.php
+++ b/src/SerializeTrait.php
@@ -7,7 +7,6 @@
namespace karmabunny\kb;
use ReflectionProperty;
-use ReturnTypeWillChange;
/**
* Implements a PHP serialiser.
@@ -18,13 +17,6 @@
*
* You can extend, or restrict, serialization per class by overriding
* the `getSerializedProperties()` method.
- *
- * This provides compatibility with the `Serializable` interface. Modern
- * PHP (7.4+) will use the magic `__serialize()/__unserialize()` methods if
- * available, but still prefers the "Serializable" methods.
- *
- * When overriding these methods, just override the magic ones and let this
- * trait wrap them to comply with the `Serializable` interface.
*/
trait SerializeTrait
{
@@ -55,25 +47,6 @@ protected function getSerializedProperties(): array
/** @inheritdoc */
- #[ReturnTypeWillChange]
- public function serialize()
- {
- $serialized = $this->__serialize();
- return serialize($serialized);
- }
-
-
- /** @inheritdoc */
- #[ReturnTypeWillChange]
- public function unserialize($serialized)
- {
- $serialized = unserialize($serialized);
- $this->__unserialize($serialized);
- }
-
-
- /** @inheritdoc */
- // phpcs:ignore
public function __serialize(): array
{
if ($this instanceof NotSerializable) {
@@ -86,9 +59,7 @@ public function __serialize(): array
/** @inheritdoc */
- #[ReturnTypeWillChange]
- // phpcs:ignore
- public function __unserialize(array $serialized)
+ public function __unserialize(array $serialized): void
{
if ($this instanceof DataObject) {
$this->update($serialized);
diff --git a/src/Shell.php b/src/Shell.php
index 49837d1..215c92b 100644
--- a/src/Shell.php
+++ b/src/Shell.php
@@ -35,7 +35,7 @@ class Shell
* @param array $args keyed args
* @return string escaped cmd string
*/
- public static function escape(string $cmd, array $args)
+ public static function escape(string $cmd, array $args): string
{
return preg_replace_callback('/{([^}]+)}/', function($matches) use ($args) {
$index = $matches[1];
@@ -54,7 +54,7 @@ public static function escape(string $cmd, array $args)
* @param mixed $args
* @return string
*/
- public static function runSync(string $dir, string $cmd, ...$args)
+ public static function runSync(string $dir, string $cmd, mixed ...$args): string
{
$shell = self::run([
'cwd' => $dir,
@@ -79,7 +79,7 @@ public static function runSync(string $dir, string $cmd, ...$args)
* @param mixed $args
* @return Generator
*/
- public static function runAsync(string $dir, string $cmd, ...$args)
+ public static function runAsync(string $dir, string $cmd, mixed ...$args): Generator
{
$shell = self::run([
'cwd' => $dir,
@@ -115,7 +115,7 @@ public static function runAsync(string $dir, string $cmd, ...$args)
* - env - `string[]`
* @return ShellOutput
*/
- public static function run($config)
+ public static function run(string|array|ShellOptions $config): ShellOutput
{
$config = ShellOptions::parse($config);
diff --git a/src/ShellOptions.php b/src/ShellOptions.php
index e5c22fb..7ea4dc0 100644
--- a/src/ShellOptions.php
+++ b/src/ShellOptions.php
@@ -12,28 +12,28 @@
class ShellOptions extends Collection
{
/** @var string required */
- public $cmd;
+ public string $cmd = '';
/** @var array */
- public $args = [];
+ public array $args = [];
/** @var string|null */
- public $cwd = null;
+ public ?string $cwd = null;
- /** @var string[] */
- public $env = [];
+ /** @var array */
+ public array $env = [];
/** @var string|array|resource|false */
- public $stdin = 'pipe';
+ public mixed $stdin = 'pipe';
/** @var string|array|resource|false */
- public $stdout = 'pipe';
+ public mixed $stdout = 'pipe';
/** @var string|array|resource|false */
- public $stderr = 'pipe';
+ public mixed $stderr = 'pipe';
/** @var int Limit for fgets() in bytes. */
- public $chunk_size = 1024;
+ public int $chunk_size = 1024;
/**
@@ -46,7 +46,7 @@ class ShellOptions extends Collection
* @param string|array|ShellOptions $config
* @return ShellOptions
*/
- public static function parse($config)
+ public static function parse(string|array|ShellOptions $config): self
{
if ($config instanceof self) {
return clone $config;
@@ -108,7 +108,7 @@ public function getCommand(): string
* @param resource|array|string $descriptor
* @return resource|array
*/
- private static function parseDescriptor(string $mode, $descriptor)
+ private static function parseDescriptor(string $mode, mixed $descriptor): mixed
{
// Resource, cool.
if (is_resource($descriptor)) {
diff --git a/src/ShellOutput.php b/src/ShellOutput.php
index 1c1fc0d..151b8c4 100644
--- a/src/ShellOutput.php
+++ b/src/ShellOutput.php
@@ -22,29 +22,29 @@ class ShellOutput
/** @var int milliseconds */
- static $SELECT_TIMEOUT = 100;
+ public static int $SELECT_TIMEOUT = 100;
/** @var ShellOptions */
- public $config;
+ public ShellOptions $config;
/** @var resource */
- public $handle;
+ public mixed $handle;
/** @var int */
- public $pid = -1;
+ public int $pid = -1;
/** @var bool */
- public $running = false;
+ public bool $running = false;
/** @var int|false */
- public $exit = false;
+ public int|false $exit = false;
/** @var array [ stdin, stdout, stderr ] */
- private $pipes;
+ private array $pipes;
/** @var array resource, string array */
- private $descriptors;
+ private array $descriptors;
/**
@@ -53,7 +53,7 @@ class ShellOutput
* @param resource $handle from proc_open()
* @param array $pipes from proc_open()
*/
- public function __construct(ShellOptions $config, $handle, array $pipes)
+ public function __construct(ShellOptions $config, mixed $handle, array $pipes)
{
$this->config = $config;
$this->handle = $handle;
diff --git a/src/SortFieldsTrait.php b/src/SortFieldsTrait.php
index 850dbb6..b183cf8 100644
--- a/src/SortFieldsTrait.php
+++ b/src/SortFieldsTrait.php
@@ -6,6 +6,8 @@
namespace karmabunny\kb;
+use karmabunny\interfaces\SortableInterface;
+
/**
* A simple sorter for object.
*
@@ -16,9 +18,9 @@
*
* All comparisons are done with the spaceship operator.
*
- * @see Sortable
* @see Arrays::sort
*
+ * @mixin SortableInterface
* @package karmabunny\kb
*/
trait SortFieldsTrait
@@ -48,7 +50,7 @@ public abstract function getSortKey(): string;
* @param string $mode
* @return int
*/
- public function compare($other, $mode = 'default'): int
+ public function compare(mixed $other, string $mode = 'default'): int
{
if ($other instanceof static) {
// Our default sort key.
diff --git a/src/Text.php b/src/Text.php
index 6dcf9c9..8be84b4 100644
--- a/src/Text.php
+++ b/src/Text.php
@@ -55,23 +55,23 @@ class Text {
/** @var string */
- static $ENCODING = 'UTF-8';
+ public static string $ENCODING = 'UTF-8';
/** @var int */
- static $MIN_SIMILAR_PERCENT = 85;
+ public static int $MIN_SIMILAR_PERCENT = 85;
/** @var int */
- static $DISTANCE_FACTOR = 10;
+ public static int $DISTANCE_FACTOR = 10;
/** @var array */
- static $ALPHA_RULES = [
+ public static array $ALPHA_RULES = [
"a4 e3 o0D ilL1!| `’",
"AA EE OOO IIIIII ''",
];
/** @var array|null Not for public use. */
- static $_map = null;
+ public static ?array $_map = null;
/**
@@ -89,7 +89,7 @@ class Text {
* @param int $flags
* @return string
*/
- public static function normalize(string $str, $flags = self::NORMALIZE_ALL)
+ public static function normalize(string $str, int $flags = self::NORMALIZE_ALL): string
{
if ($flags & self::NORMALIZE_ALPHA) {
$str = self::normalizeAlpha($str);
@@ -119,7 +119,7 @@ public static function normalize(string $str, $flags = self::NORMALIZE_ALL)
* @param string $str
* @return string
*/
- public static function normalizeAlpha(string $str)
+ public static function normalizeAlpha(string $str): string
{
list($find, $replace) = self::$ALPHA_RULES;
return strtr($str, $find, $replace);
@@ -145,7 +145,7 @@ public static function normalizeAlpha(string $str)
* @param array $map
* @return string
*/
- public static function normalizeMultibyte(string $str, array &$map = [])
+ public static function normalizeMultibyte(string $str, array &$map = []): string
{
$matches = [];
@@ -174,7 +174,7 @@ public static function normalizeMultibyte(string $str, array &$map = [])
* @param int $flags one of the normalisation flags
* @return float 0-100 bigger is better
*/
- public static function similarity(string $str1, string $str2, $flags = self::NORMALIZE_ALL)
+ public static function similarity(string $str1, string $str2, int $flags = self::NORMALIZE_ALL): float
{
if ($flags) {
self::$_map = [];
@@ -197,7 +197,7 @@ public static function similarity(string $str1, string $str2, $flags = self::NOR
* @param int $flags one of the normalisation flags
* @return int lower is better (or -1 if too long)
*/
- public static function compare(string $str1, string $str2, $flags = self::NORMALIZE_ALL)
+ public static function compare(string $str1, string $str2, int $flags = self::NORMALIZE_ALL): int
{
if ($flags) {
self::$_map = [];
@@ -223,7 +223,7 @@ public static function compare(string $str1, string $str2, $flags = self::NORMAL
* @param int $flags one of the normalisation flags
* @return bool
*/
- public static function similar(string $str1, string $str2, $flags = self::NORMALIZE_ALL)
+ public static function similar(string $str1, string $str2, int $flags = self::NORMALIZE_ALL): bool
{
if ($flags) {
self::$_map = [];
@@ -270,7 +270,7 @@ public static function similar(string $str1, string $str2, $flags = self::NORMAL
* @param int $flags one of the normalisation flags
* @return string[] subset of 'options' in order of closeness
*/
- public static function find(string $needle, array $haystack, $max = 5, $flags = self::NORMALIZE_ALL): array
+ public static function find(string $needle, array $haystack, int $max = 5, int $flags = self::NORMALIZE_ALL): array
{
self::$_map = [];
@@ -335,7 +335,7 @@ public static function find(string $needle, array $haystack, $max = 5, $flags =
* @param int $flags
* @return array
*/
- public static function startsWith(string $needle, array $haystack, $max = 5, $flags = self::NORMALIZE_ALL): array
+ public static function startsWith(string $needle, array $haystack, int $max = 5, int $flags = self::NORMALIZE_ALL): array
{
$flags |= self::FIND_STARTS_WITH;
return self::find($needle, $haystack, $max, $flags);
@@ -351,7 +351,7 @@ public static function startsWith(string $needle, array $haystack, $max = 5, $fl
* @param int $end Optional number of characters to keep from the end of string. Eg `2` = `***le`
* @return string Eg `*****`|`A****`|`****e`|`A***e`
*/
- public static function mask(string $word, $mask_char = '*', $start = 0, $end = 0)
+ public static function mask(string $word, string $mask_char = '*', int $start = 0, int $end = 0): string
{
if (empty($word)) return '';
if (empty($mask_char)) $mask_char = '*';
@@ -384,11 +384,11 @@ public static function mask(string $word, $mask_char = '*', $start = 0, $end = 0
*
* @param string $word
* @param string $preset Text::MASK_TYPE_*
- * @param string|null $mask_char Optional masking character. Default of `*`
+ * @param string $mask_char Optional masking character. Default of `*`
* @return string
* @throws Exception Unknown preset
*/
- public static function maskPreset(string $word, string $preset, $mask_char = '*')
+ public static function maskPreset(string $word, string $preset, string $mask_char = '*'): string
{
switch ($preset)
{
diff --git a/src/Time.php b/src/Time.php
index 6a9b552..b63055f 100644
--- a/src/Time.php
+++ b/src/Time.php
@@ -48,7 +48,7 @@ class Time
/** @var array{float,float}|null */
- protected static $time_travel = null;
+ protected static ?array $time_travel = null;
/**
@@ -90,7 +90,7 @@ public static function getDate(string $modifier = 'now'): DateTimeImmutable
* @param DateTimeImmutable|string|float|null $date
* @return void
*/
- public static function setTimeTravel($date): void
+ public static function setTimeTravel(DateTimeImmutable|string|float|null $date): void
{
if ($date === null) {
self::$time_travel = null;
@@ -142,18 +142,14 @@ public static function resume(): void
/**
* Timestamp as an integer in microseconds.
*
- * This uses hrtime for 7.2+ with a microtime fallback.
- * You can force microtime by passing false.
- *
* Note, if using hrtime the timestamp _is not_ a unix epoch.
*
- * @param bool $hrtime Use high-resolution if available.
+ * @param bool $hrtime Use high-resolution (default)
* @return int microseconds
*/
- public static function utime($hrtime = true): int
+ public static function utime(bool $hrtime = true): int
{
- if ($hrtime and function_exists('hrtime')) {
- // phpcs:ignore
+ if ($hrtime) {
return intdiv(hrtime(true), 1000);
}
else {
@@ -171,7 +167,7 @@ public static function utime($hrtime = true): int
* @param int $timediff Amount of time that has passed, in seconds.
* @return string
**/
- public static function timeAgo(int $timediff)
+ public static function timeAgo(int $timediff): string
{
$timediff = (int) $timediff;
@@ -209,15 +205,13 @@ public static function timeAgo(int $timediff)
* - classic PHP date parsing
* - timezones
*
- * @param string|int|float|DateTimeInterface $value
+ * @param mixed $value
* @param string|DateTimeZone|null $zone
* @return DateTimeInterface
* @throws InvalidArgumentException
*/
- public static function parse($value, $zone = null): DateTimeInterface
+ public static function parse(mixed $value, string|DateTimeZone|null $zone = null): DateTimeInterface
{
- /** @var mixed $value */
-
// Also parse timezones while we're here.
if (is_string($zone)) {
$zone = new DateTimeZone($zone);
@@ -302,14 +296,12 @@ public static function parseFloat(float $timestamp, ?DateTimeZone $zone = null):
*
* `T101 => 'T10:10:00'`
*
- * @param string|int $time
+ * @param mixed $time
* @param bool $big_endian left or right aligned number parsing
* @return string|null `T HH:MM:II.SSS`
*/
- public static function parseTimeString($time, $big_endian = true)
+ public static function parseTimeString(mixed $time, bool $big_endian = true): ?string
{
- /** @var mixed $time */
-
// 24 hour time.
if (is_numeric($time)) {
$args = [];
@@ -445,8 +437,7 @@ public static function parseInterval(string $value): DateInterval
/**
* Convert any date interface into a datetime.
*
- * This exists in PHP8+ as `DateTime::createFromInterface()`.
- *
+ * @deprecated use DateTime::createFromInterface() instead
* @param DateTimeInterface $interface
* @return DateTime
*/
@@ -466,8 +457,7 @@ public static function toDateTime(DateTimeInterface $interface): DateTime
/**
* Convert any date interface into a immutable.
*
- * This exists in PHP8+ as `DateTimeImmutable::createFromInterface()`.
- *
+ * @deprecated use DateTimeImmutable::createFromInterface() instead
* @param DateTimeInterface $interface
* @return DateTimeImmutable
*/
@@ -529,12 +519,12 @@ public static function toTimeFloat(DateTimeInterface $date): float
* Convert a timestamp to a date string in the given timezone
*
* @param string $timezone
- * @param int|float $timestamp
+ * @param float $timestamp
* @param string $format
* @return string The date string in the requested format
* @throws InvalidArgumentException
*/
- public static function utcTimeToDate(string $timezone, $timestamp, string $format = 'Y-m-d H:i:s'): string
+ public static function utcTimeToDate(string $timezone, float $timestamp, string $format = 'Y-m-d H:i:s'): string
{
$timezone_dt = new DateTimeZone($timezone);
$date = self::parseFloat($timestamp, $timezone_dt);
@@ -644,7 +634,7 @@ public static function localNow(string $timezone, string $format = 'Y-m-d H:i:s'
* @param DateInterval|array|string $intervals
* @return DateInterval
*/
- public static function modifyInterval(...$intervals)
+ public static function modifyInterval(mixed ...$intervals): DateInterval
{
if (empty($intervals)) {
return new DateInterval('P0D');
@@ -839,10 +829,10 @@ public static function getIntervalTotal(DateInterval $interval, string $unit = '
* @param string|null $gap A date modifier, a gap between each period
* @return Generator [start, end]
*/
- public static function periods(DateTimeInterface $start, DateTimeInterface $end, string $period, ?string $gap = null)
+ public static function periods(DateTimeInterface $start, DateTimeInterface $end, string $period, ?string $gap = null): Generator
{
- $start = self::toDateTimeImmutable($start);
- $end = self::toDateTimeImmutable($end);
+ $start = DateTimeImmutable::createFromInterface($start);
+ $end = DateTimeImmutable::createFromInterface($end);
$periodStart = $start;
$periodEnd = $end;
@@ -870,9 +860,9 @@ public static function periods(DateTimeInterface $start, DateTimeInterface $end,
*
* @param DateTimeInterface $start
* @param DateTimeInterface $end
- * @return iterable
+ * @return Generator
*/
- public static function between(DateTimeInterface $start, DateTimeInterface $end)
+ public static function between(DateTimeInterface $start, DateTimeInterface $end): Generator
{
$periods = self::periods($start, $end, '+1 day');
foreach ($periods as $days) yield $days[0];
@@ -894,9 +884,9 @@ public static function between(DateTimeInterface $start, DateTimeInterface $end)
* @param int $year
* @param int $from 1-indexed, inclusive
* @param int $to 1-indexed, inclusive
- * @return iterable
+ * @return Generator
*/
- public static function months(int $year, int $from, int $to)
+ public static function months(int $year, int $from, int $to): Generator
{
while ($from <= $to) {
@@ -935,9 +925,9 @@ public static function months(int $year, int $from, int $to)
* @param int $year
* @param int $from 1-indexed, inclusive
* @param int $to 1-indexed, inclusive
- * @return iterable
+ * @return Generator
*/
- public static function monthGrid(int $year, int $from, int $to)
+ public static function monthGrid(int $year, int $from, int $to): Generator
{
$months = self::months($year, $from, $to);
@@ -990,10 +980,10 @@ public static function monthGrid(int $year, int $from, int $to)
* - minute
* - second
*
- * @param array|string $config
+ * @param array $config
* @return DateTimeImmutable
*/
- public static function now($config = []): DateTimeInterface
+ public static function now(array $config = []): DateTimeInterface
{
$now = new DateTimeImmutable();
@@ -1047,7 +1037,7 @@ public static function weekdays(int $length = 0): array
* @param int $day day of the month, useful if using a day in the format
* @return string[]
*/
- public static function monthOptions(int $length = 9, string $format = 'F', int $day = 1)
+ public static function monthOptions(int $length = 9, string $format = 'F', int $day = 1): array
{
$options = [];
@@ -1096,7 +1086,7 @@ public static function years(int $length = 5, ?int $year = null): array
* @param DateTimeInterface|int|null $now
* @return string
*/
- public static function getTimezoneOffset($timezone, $now = null): string
+ public static function getTimezoneOffset(string|DateTimeZone $timezone, DateTimeInterface|int|null $now = null): string
{
if (is_string($timezone)) {
$timezone = new DateTimeZone($timezone);
diff --git a/src/TimeZones.php b/src/TimeZones.php
index a841f2a..58831eb 100644
--- a/src/TimeZones.php
+++ b/src/TimeZones.php
@@ -18,7 +18,7 @@
class TimeZones
{
- protected static $map = null;
+ protected static ?array $map = null;
/**
diff --git a/src/ToJsonTrait.php b/src/ToJsonTrait.php
index 6177a1e..afb6099 100755
--- a/src/ToJsonTrait.php
+++ b/src/ToJsonTrait.php
@@ -1,12 +1,16 @@
toJson();
}
diff --git a/src/UpdateStrictTrait.php b/src/UpdateStrictTrait.php
index bb9f7dc..cdc6292 100644
--- a/src/UpdateStrictTrait.php
+++ b/src/UpdateStrictTrait.php
@@ -7,6 +7,7 @@
namespace karmabunny\kb;
use InvalidArgumentException;
+use karmabunny\interfaces\ConfigurableInterface;
/**
* This modifies the behaviour of a DataObject/Collection so that only
@@ -15,6 +16,7 @@
* This extends the behaviour of {@see UpdateTidyTrait}, where it will throw
* errors if a field is missing instead of silently ignoring it.
*
+ * @mixin ConfigurableInterface
* @package karmabunny\kb
*/
trait UpdateStrictTrait
@@ -26,7 +28,7 @@ trait UpdateStrictTrait
* @param iterable $config
* @return void
*/
- public function update($config)
+ public function update(iterable $config): void
{
$fields = array_fill_keys(static::getProperties(), true);
diff --git a/src/UpdateTidyTrait.php b/src/UpdateTidyTrait.php
index d97564d..1f3b9e6 100644
--- a/src/UpdateTidyTrait.php
+++ b/src/UpdateTidyTrait.php
@@ -6,12 +6,15 @@
namespace karmabunny\kb;
+use karmabunny\interfaces\ConfigurableInterface;
+
/**
* This is functional the same as {@see UpdateTrait} only it uses the
* `getProperties()` helper to determine which fields belong to the class.
*
* To raise errors on unknown fields {@see UpdateStrictTrait}.
*
+ * @mixin ConfigurableInterface
* @package karmabunny\kb
*/
trait UpdateTidyTrait
@@ -23,7 +26,7 @@ trait UpdateTidyTrait
* @param iterable $config
* @return void
*/
- public function update($config)
+ public function update(iterable $config): void
{
$fields = array_fill_keys(static::getProperties(), true);
diff --git a/src/UpdateTrait.php b/src/UpdateTrait.php
index f16098f..8bc62d6 100644
--- a/src/UpdateTrait.php
+++ b/src/UpdateTrait.php
@@ -6,6 +6,8 @@
namespace karmabunny\kb;
+use karmabunny\interfaces\ConfigurableInterface;
+
/**
* This implements basic `update()` behaviour for an object.
*
@@ -14,6 +16,7 @@
*
* To raise errors on unknown fields {@see UpdateStrictTrait}.
*
+ * @mixin ConfigurableInterface
* @package karmabunny\kb
*/
trait UpdateTrait
@@ -23,7 +26,7 @@ trait UpdateTrait
* @param iterable $config
* @return void
*/
- public function update($config)
+ public function update(iterable $config): void
{
foreach ($config as $key => $item) {
if (!property_exists($this, $key)) continue;
diff --git a/src/Url.php b/src/Url.php
index 660c51a..3811879 100644
--- a/src/Url.php
+++ b/src/Url.php
@@ -18,28 +18,28 @@ class Url extends DataObject
use UpdateVirtualTrait;
/** @var string|null */
- public $scheme;
+ public ?string $scheme = null;
/** @var string|null */
- public $host;
+ public ?string $host = null;
- /** @var string|null */
- public $port;
+ /** @var int|null */
+ public ?int $port = null;
/** @var string|null */
- public $user;
+ public ?string $user = null;
/** @var string|null */
- public $pass;
+ public ?string $pass = null;
/** @var string|null */
- public $path;
+ public ?string $path = null;
/** @var array after the question mark ? */
- public $query = [];
+ public mixed $query = [];
/** @var string|null after the hashmark # */
- public $fragment;
+ public ?string $fragment = null;
/** @inheritdoc */
@@ -58,7 +58,7 @@ public function virtual(): array
* @return static
* @throws UrlDecodeException
*/
- public function setQuery($query)
+ public function setQuery(array|string $query): static
{
if (is_array($query)) {
$this->query = $query;
@@ -77,7 +77,7 @@ public function setQuery($query)
* @return static
* @throws UrlDecodeException
*/
- public function addParams(array $query)
+ public function addParams(array $query): static
{
$this->query = array_merge($this->query, $query);
return $this;
@@ -91,7 +91,7 @@ public function addParams(array $query)
* @param mixed $value
* @return static
*/
- public function setParam(string $name, $value)
+ public function setParam(string $name, mixed $value): static
{
$this->query[$name] = $value;
return $this;
@@ -108,7 +108,7 @@ public function setParam(string $name, $value)
* @param mixed $value
* @return static
*/
- public function addParam(string $name, $value)
+ public function addParam(string $name, mixed $value): static
{
if (array_key_exists($name, $this->query)) {
$existing = $this->query[$name];
@@ -133,7 +133,7 @@ public function addParam(string $name, $value)
* @param string $name
* @return static
*/
- public function removeParam(string $name)
+ public function removeParam(string $name): static
{
unset($this->query[$name]);
return $this;
@@ -157,7 +157,7 @@ public function hasParam(string $name): bool
*
* @return void
*/
- public function normalize()
+ public function normalize(): void
{
if ($this->scheme) {
$default = self::getDefaultPort($this->scheme);
@@ -256,10 +256,10 @@ public function __toString(): string
* @return self
* @throws UrlParseException
*/
- public static function parse(string $url)
+ public static function parse(string $url): self
{
$config = parse_url($url);
- if ($config === false) {
+ if (!is_array($config)) {
throw new UrlParseException("Could not parse URL: {$url}");
}
return new self($config);
@@ -296,7 +296,7 @@ public static function decode(string $query): array
/**
*
- * @return array
+ * @return array
*/
public static function getDefaultPorts(): array
{
@@ -310,7 +310,7 @@ public static function getDefaultPorts(): array
* @param string $scheme
* @return null|int
*/
- public static function getDefaultPort(string $scheme)
+ public static function getDefaultPort(string $scheme): ?int
{
$ports = self::getDefaultPorts();
return $ports[$scheme] ?? null;
@@ -336,7 +336,7 @@ public static function getDefaultPort(string $scheme)
* @param string|array $parts
* @return string
*/
- public static function build(...$parts): string
+ public static function build(mixed ...$parts): string
{
if (empty($parts)) return '/';
diff --git a/src/UrlDecodeException.php b/src/UrlDecodeException.php
index 871112e..9f3cbbf 100644
--- a/src/UrlDecodeException.php
+++ b/src/UrlDecodeException.php
@@ -15,14 +15,14 @@ class UrlDecodeException extends UrlException
{
/** @var string|null */
- public $query;
+ public ?string $query = null;
/**
*
* @param string $query
* @return static
*/
- public function setQuery(string $query)
+ public function setQuery(string $query): static
{
$this->query = $query;
return $this;
diff --git a/src/Uuid.php b/src/Uuid.php
index 1102454..9ea7ff5 100644
--- a/src/Uuid.php
+++ b/src/Uuid.php
@@ -97,7 +97,7 @@ public static function nil(): string
* @return string
* @throws Exception Not enough entropy
*/
- public static function uuid1($options = 0): string
+ public static function uuid1(int $options = 0): string
{
// 60-bit time in 100ths of nanoseconds
$timestamp = self::getSubNanoTime((bool) ($options & self::V1_LAZY));
@@ -399,7 +399,7 @@ private static function getMacAddress()
*
* @return int 16-bit number.
*/
- private static function getSequence()
+ private static function getSequence(): int
{
static $base;
if (!$base) $base = getmypid() ?: 1;
diff --git a/src/ValidErrorsTrait.php b/src/ValidErrorsTrait.php
index 66c8980..fffe2f1 100644
--- a/src/ValidErrorsTrait.php
+++ b/src/ValidErrorsTrait.php
@@ -2,10 +2,13 @@
namespace karmabunny\kb;
+use karmabunny\interfaces\ValidatesInterface;
+
/**
* This extends the Validates interface with a `valid()` method that returns a
* boolean. The errors are stored in the model.
*
+ * @mixin ValidatesInterface
* @package karmabunny\kb
*/
trait ValidErrorsTrait
@@ -25,7 +28,7 @@ trait ValidErrorsTrait
* @param string|null $scenario
* @throws ValidationException
*/
- public abstract function validate(?string $scenario = null);
+ public abstract function validate(?string $scenario = null): void;
/**
diff --git a/src/ValidationException.php b/src/ValidationException.php
index 262ee63..47dca2f 100644
--- a/src/ValidationException.php
+++ b/src/ValidationException.php
@@ -22,7 +22,7 @@ class ValidationException extends Exception implements ValidationExceptionInterf
*
* @var array [ item => [errors] ]
*/
- public $errors = [];
+ public array $errors = [];
/**
@@ -44,7 +44,7 @@ public function getErrors(): array
* @param array $errors
* @return static
*/
- public function addErrors(array $errors)
+ public function addErrors(array $errors): static
{
foreach ($errors as $name => $messages) {
if (isset($this->errors[$name])) {
diff --git a/src/Validity.php b/src/Validity.php
index 24cacd2..3bc9535 100644
--- a/src/Validity.php
+++ b/src/Validity.php
@@ -16,6 +16,9 @@
*
* Used with the {@see RulesStaticValidator} class.
*
+ * Note, these methods accept mixed rather than strong 'string' types because
+ * often we're validating data from user input, which may contain nulls or other types.
+ *
* @package karmabunny\kb
*/
class Validity
@@ -27,13 +30,14 @@ class Validity
* @example
* $valid->check('name', 'length', 1, 100)
*
- * @param string $val The value
+ * @param mixed $val The value
* @param int $min Minimum length
* @param int $max Maximum length
* @throws ValidationException If item is too short or too long
*/
- public static function length($val, $min, $max = PHP_INT_MAX)
+ public static function length(mixed $val, int $min, int $max = PHP_INT_MAX): void
{
+ $val = (string) $val;
$len = mb_strlen($val);
if ($len < $min) {
throw new ValidationException("Shorter than minimum allowed length of {$min}");
@@ -53,11 +57,12 @@ public static function length($val, $min, $max = PHP_INT_MAX)
* @example
* $valid->check('email', 'email')
*
- * @param string $val email address
+ * @param mixed $val email address
* @throws ValidationException
*/
- public static function email($val)
+ public static function email(mixed $val): void
{
+ $val = (string) $val;
$regex = '/^[^@]+@[^@.]+\.[^@]+$/iD';
if (!preg_match($regex, $val)) {
@@ -78,11 +83,12 @@ public static function email($val)
* @example
* $valid->check('password', 'password')
*
- * @param string $val Password to validate
+ * @param mixed $val Password to validate
* @throws ValidationException
*/
- public static function password($val)
+ public static function password(mixed $val): void
{
+ $val = (string) $val;
$errs = [];
if (mb_strlen($val) < 8) {
@@ -113,13 +119,14 @@ public static function password($val)
* @example
* $valid->check('mobile', 'phone', 10)
*
- * @param string $val Phone number
+ * @param mixed $val Phone number
* @param int $min_digits Minimum number of digits required in phone number.
* This can be less than 8 for fields which allow short numbers like 000 or 13 11 66
* @throws ValidationException
*/
- public static function phone($val, $min_digits = 8)
+ public static function phone(mixed $val, int $min_digits = 8): void
{
+ $val = (string) $val;
$min_digits = (int) $min_digits;
if ($min_digits <= 0) $min_digits = 8;
@@ -155,12 +162,12 @@ public static function phone($val, $min_digits = 8)
* @example
* $valid->check('region_id', 'positiveInt')
*
- * @param string $val Value to check
+ * @param mixed $val Value to check
* @throws ValidationException
*/
- public static function positiveInt($val)
+ public static function positiveInt(mixed $val): void
{
- if (preg_match('/[^0-9]/', $val)) {
+ if (preg_match('/[^0-9]/', (string) $val)) {
throw new ValidationException("Value must be a whole number that is greater than zero");
}
@@ -181,10 +188,10 @@ public static function positiveInt($val)
* @example
* $valid->check('name', 'proseText')
*
- * @param string $str
+ * @param mixed $str
* @throws ValidationException
*/
- public static function proseText($str)
+ public static function proseText(mixed $str): void
{
// pL = letters, pN = numbers
if (preg_match('/[^-\pL\pN \'"\/!?@#$%&():;.,]/u', (string) $str)) {
@@ -199,13 +206,13 @@ public static function proseText($str)
* @example
* $valid->check('date_published', 'dateMySQL')
*
- * @param string $val Value to check
+ * @param mixed $val Value to check
* @throws ValidationException
*/
- public static function dateMySQL($val)
+ public static function dateMySQL(mixed $val): void
{
$matches = null;
- if (!preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/', $val, $matches)) {
+ if (!preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/', (string) $val, $matches)) {
throw new ValidationException('Invalid date format');
}
@@ -229,13 +236,13 @@ public static function dateMySQL($val)
* @example
* $valid->check('event_time', 'timeMySQL')
*
- * @param string $val Value to check
+ * @param mixed $val Value to check
* @throws ValidationException
*/
- public static function timeMySQL($val)
+ public static function timeMySQL(mixed $val): void
{
$matches = null;
- if (!preg_match('/^([0-9]{2}):([0-9]{2}):([0-9]{2})$/', $val, $matches)) {
+ if (!preg_match('/^([0-9]{2}):([0-9]{2}):([0-9]{2})$/', (string) $val, $matches)) {
throw new ValidationException('Invalid time format');
}
@@ -259,13 +266,13 @@ public static function timeMySQL($val)
* @example
* $valid->check('start_date', 'datetimeMySQL')
*
- * @param string $val Value to check
+ * @param mixed $val Value to check
* @throws ValidationException
*/
- public static function datetimeMySQL($val)
+ public static function datetimeMySQL(mixed $val): void
{
$matches = null;
- if (!preg_match('/^([0-9]{4}-[0-9]{2}-[0-9]{2}) ([0-9]{2}:[0-9]{2}:[0-9]{2})$/', $val, $matches)) {
+ if (!preg_match('/^([0-9]{4}-[0-9]{2}-[0-9]{2}) ([0-9]{2}:[0-9]{2}:[0-9]{2})$/', (string) $val, $matches)) {
throw new ValidationException('Invalid datedate format');
}
@@ -283,7 +290,7 @@ public static function datetimeMySQL($val)
* @param array $vals Values to check
* @throws ValidationException
*/
- public static function oneRequired(array $vals)
+ public static function oneRequired(array $vals): void
{
foreach ($vals as $v) {
if (is_array($v) and count($v) > 0) {
@@ -306,7 +313,7 @@ public static function oneRequired(array $vals)
* @param array $vals Values to check
* @throws ValidationException
*/
- public static function allMatch(array $vals)
+ public static function allMatch(array $vals): void
{
$unique = array_unique($vals);
if (count($unique) > 1) {
@@ -325,7 +332,7 @@ public static function allMatch(array $vals)
* @param array $vals Values to check
* @throws ValidationException
*/
- public static function allUnique(array $vals)
+ public static function allUnique(array $vals): void
{
$unique = array_unique($vals);
if (count($unique) != count($vals)) {
@@ -344,7 +351,7 @@ public static function allUnique(array $vals)
* @param array $allowed
* @throws ValidationException
*/
- public static function inArray($val, array $allowed)
+ public static function inArray(mixed $val, array $allowed): void
{
if (!in_array($val, $allowed)) {
throw new ValidationException('Invalid value');
@@ -377,10 +384,10 @@ public static function allInArray(array $val, array $allowed)
* @example
* $valid->check('cost', 'numeric')
*
- * @param string $val
+ * @param mixed $val
* @throws ValidationException
*/
- public static function numeric($val)
+ public static function numeric(mixed $val): void
{
if (!is_numeric($val)) {
throw new ValidationException('Value must be a number');
@@ -394,10 +401,10 @@ public static function numeric($val)
* @example
* $valid->check('active', 'binary')
*
- * @param string|int $val
+ * @param mixed $val
* @throws ValidationException
*/
- public static function binary($val)
+ public static function binary(mixed $val): void
{
if ($val !== '1' and $val !== 1 and $val !== '0' and $val !== 0) {
throw new ValidationException('Value must be a "1" or "0"');
@@ -412,11 +419,11 @@ public static function binary($val)
* $valid->check('cost', 'range', 0, 5000)
*
* @param string $val
- * @param number $min The minimum the value may be
- * @param number $max The maximum the value may be
+ * @param int|float $min The minimum the value may be
+ * @param int|float $max The maximum the value may be
* @throws ValidationException
*/
- public static function range($val, $min, $max)
+ public static function range(mixed $val, int|float $min, int|float $max): void
{
static::numeric($val);
@@ -437,7 +444,7 @@ public static function range($val, $min, $max)
* @param string $max (optional) A date string (compatible with strtotime) for the maximum of the date range.
* @param bool $enforce_ordering (optional) Ensures that the start date is less than or equal to the end date. On by default.
*/
- public static function dateRange(array $vals, $min = null, $max = null, $enforce_ordering = true)
+ public static function dateRange(array $vals, ?string $min = null, ?string $max = null, bool $enforce_ordering = true): void
{
if (count($vals) != 2) {
throw new InvalidArgumentException('Incorrect number of fields. A date range must only contain two dates: a start and an end date.');
@@ -481,7 +488,7 @@ public static function dateRange(array $vals, $min = null, $max = null, $enforce
* @return void
* @throws ValidationException If the value doesn't match the pattern
*/
- public static function regex($val, $pattern)
+ public static function regex(string $val, string $pattern): void
{
if (!preg_match($pattern, $val)) {
throw new ValidationException('Incorrect format');
@@ -495,7 +502,7 @@ public static function regex($val, $pattern)
* @return void
* @throws ValidationException If the value isn't a valid IPv4 address
*/
- public static function ipv4Addr($val)
+ public static function ipv4Addr(string $val): void
{
if (!preg_match('/^[0-9]+(?:\.[0-9]+){3}$/', $val)) {
throw new ValidationException('Invalid IP address');
@@ -515,7 +522,7 @@ public static function ipv4Addr($val)
* @return void
* @throws ValidationException If the value isn't a valid IPv4 CIDR block
*/
- public static function ipv4Cidr($val)
+ public static function ipv4Cidr(string $val): void
{
if (strpos($val, '/') === false) {
throw new ValidationException('Invalid CIDR block');
@@ -540,7 +547,7 @@ public static function ipv4Cidr($val)
* @return void
* @throws ValidationException If the value isn't a valid IPv4 address or CIDR block
*/
- public static function ipv4AddrOrCidr($val)
+ public static function ipv4AddrOrCidr(string $val): void
{
if (strpos($val, '/') === false) {
self::ipv4Addr($val);
diff --git a/src/VirtualArrayTrait.php b/src/VirtualArrayTrait.php
index dd6a35c..97058fa 100644
--- a/src/VirtualArrayTrait.php
+++ b/src/VirtualArrayTrait.php
@@ -7,10 +7,10 @@
namespace karmabunny\kb;
use ArrayAccess;
-use ReturnTypeWillChange;
/**
*
+ * @mixin ArrayAccess
*/
trait VirtualArrayTrait
{
@@ -23,8 +23,8 @@ trait VirtualArrayTrait
public abstract function fields(): array;
- #[ReturnTypeWillChange]
- public function offsetExists($offset)
+ /** @inheritdoc */
+ public function offsetExists(mixed $offset): bool
{
if (!is_numeric($offset)) {
$fields = $this->fields();
@@ -40,8 +40,8 @@ public function offsetExists($offset)
}
- #[ReturnTypeWillChange]
- public function offsetGet($offset)
+ /** @inheritdoc */
+ public function offsetGet(mixed $offset): mixed
{
if (!is_numeric($offset)) {
$fields = $this->fields();
diff --git a/src/VirtualMethodsTrait.php b/src/VirtualMethodsTrait.php
index f4502ea..907d19f 100644
--- a/src/VirtualMethodsTrait.php
+++ b/src/VirtualMethodsTrait.php
@@ -17,7 +17,7 @@ trait VirtualMethodsTrait
* @param mixed $name
* @return mixed
*/
- public function __get($name)
+ public function __get(mixed $name): mixed
{
// TODO Test this.
if ($value = parent::__get($name)) return $value;
diff --git a/src/Wrap.php b/src/Wrap.php
index d37aa9e..7e85306 100644
--- a/src/Wrap.php
+++ b/src/Wrap.php
@@ -3,7 +3,6 @@
namespace karmabunny\kb;
use ArrayAccess;
-use Closure;
use InvalidArgumentException;
/**
@@ -38,6 +37,7 @@
* $mapped = array_map(Wrap::construct(Thing::class), $results);
* ```
*
+ * @deprecated don't use this.
* @package karmabunny/kb
*/
class Wrap
@@ -54,7 +54,7 @@ class Wrap
* @return callable (...$args) => object
* @throws InvalidArgumentException
*/
- public static function construct(string $name)
+ public static function construct(string $name): callable
{
// Validate, but also autoload things.
if (!class_exists($name, true)) {
@@ -77,7 +77,7 @@ public static function construct(string $name)
* @param string $name a class name
* @return callable ($item) => bool
*/
- public static function instanceOf(string $name)
+ public static function instanceOf(string $name): callable
{
return function ($item) use ($name) {
return (
@@ -98,7 +98,7 @@ public static function instanceOf(string $name)
* @param string $name
* @return callable (object) => mixed
*/
- public static function property(string $name)
+ public static function property(string $name): callable
{
return function ($item) use ($name) {
if (!is_object($item)) return null;
@@ -118,7 +118,7 @@ public static function property(string $name)
* @param array $args
* @return callable (object) => mixed
*/
- public static function method(string $name, ...$args)
+ public static function method(string $name, mixed ...$args): callable
{
return function ($item) use ($name, $args) {
if (!is_object($item)) return null;
@@ -137,7 +137,7 @@ public static function method(string $name, ...$args)
* @param string|int $key
* @return callable (array) => mixed
*/
- public static function item($key)
+ public static function item($key): callable
{
return function ($item) use ($key) {
if (!(
diff --git a/src/XML.php b/src/XML.php
index 939fdb3..ebee117 100644
--- a/src/XML.php
+++ b/src/XML.php
@@ -1,4 +1,5 @@
schemaValidateSource($source);
@@ -144,14 +140,11 @@ public static function validate(DOMDocument $doc, string $source)
* @param array $config
* @return DOMDocument
*/
- private static function createDocument(array &$config)
+ private static function createDocument(array &$config): DOMDocument
{
// Automatic entity loading isn't a thing anymore. Although we still
// loading for loading schemas and such. Use the 'entities' callback
// and built-in loaders for this, or build you own.
- if (PHP_VERSION_ID < 80000) {
- libxml_disable_entity_loader(true);
- }
if (!isset($config['options'])) $config['options'] = 0;
if (!isset($config['filename'])) $config['filename'] = '';
@@ -176,7 +169,7 @@ private static function createDocument(array &$config)
* @return void
* @throws XMLException
*/
- private static function collectLibXmlErrors(string $class, $filename)
+ private static function collectLibXmlErrors(string $class, ?string $filename): void
{
$errors = libxml_get_errors();
if (empty($errors)) return;
@@ -205,7 +198,7 @@ private static function collectLibXmlErrors(string $class, $filename)
*
* @return void
*/
- private static function cleanLibXml()
+ private static function cleanLibXml(): void
{
libxml_clear_errors();
libxml_use_internal_errors(false);
@@ -230,7 +223,7 @@ private static function cleanLibXml()
* @param array $entities
* @return callable (public_id, system_id, context) => resource|null
*/
- public static function allowedEntities(array $entities)
+ public static function allowedEntities(array $entities): callable
{
return function ($public_id, $system_id, $context)
use ($entities)
@@ -258,7 +251,7 @@ public static function allowedEntities(array $entities)
* @param array $prefixes
* @return callable (public_id, system_id, context) => resource|null
*/
- public static function prefixEntities(array $prefixes)
+ public static function prefixEntities(array $prefixes): callable
{
return function ($public_id, $system_id, $context)
use ($prefixes)
@@ -298,7 +291,7 @@ public static function prefixEntities(array $prefixes)
* @return void
* @throws XMLException
*/
- public static function processConditionals(DOMNode $node, array $conditions)
+ public static function processConditionals(DOMNode $node, array $conditions): void
{
/** @var DOMDocument */
$document = $node->ownerDocument ?? $node;
@@ -422,7 +415,7 @@ public static function format(string $template, array $args): DOMDocument
foreach ($args as $key => $value) {
$subjects[] = '{{' . $key . '}}';
- $replace[] = htmlspecialchars($value);
+ $replace[] = htmlspecialchars((string) $value);
}
$xml = str_replace($subjects, $replace, $template);
@@ -453,7 +446,7 @@ public static function format(string $template, array $args): DOMDocument
* @param string $type string|bool|int|float|element|list|nodes
* @return string|bool|int|float|DOMElement|DOMNode[]|Generator|null
*/
- public static function xpath(DOMNode $node, string $query, string $type = 'nodes')
+ public static function xpath(DOMNode $node, string $query, string $type = 'nodes'): mixed
{
// If 'ownerDocument' is null, then the node _is_ the document.
/** @var DOMDocument $document */
@@ -512,7 +505,7 @@ public static function xpath(DOMNode $node, string $query, string $type = 'nodes
* @param DOMNodeList $list
* @return Generator
*/
- private static function getNodeIterator(DOMNodeList $list)
+ private static function getNodeIterator(DOMNodeList $list): Generator
{
for ($i = 0; $i < $list->length; $i++) {
$item = $list->item($i);
@@ -529,7 +522,7 @@ private static function getNodeIterator(DOMNodeList $list)
* @param DOMNodeList $list
* @return Generator
*/
- private static function getElementIterator(DOMNodeList $list)
+ private static function getElementIterator(DOMNodeList $list): Generator
{
foreach (self::getNodeIterator($list) as $i => $item) {
if (!($item instanceof DOMElement)) continue;
@@ -560,7 +553,7 @@ private static function getElementIterator(DOMNodeList $list)
* @param array $params
* @return mixed
*/
- public static function enum(DOMNode $xml, string $path, array $params)
+ public static function enum(DOMNode $xml, string $path, array $params): mixed
{
$value = self::xpath($xml, $path, 'int') ?: 0;
$value = $params[$value] ?? null;
@@ -579,7 +572,7 @@ public static function enum(DOMNode $xml, string $path, array $params)
* @param DOMNode $thing
* @return bool true/false and nothing else
*/
- public static function boolean(DOMNode $thing)
+ public static function boolean(DOMNode $thing): bool
{
// No element.
$thing = self::text($thing);
@@ -634,7 +627,7 @@ public static function boolean(DOMNode $thing)
* @return DOMElement
* @throws XMLAssertException If there were no nodes with that tag
*/
- public static function expectFirst(DOMNode $parent, string $tag_name)
+ public static function expectFirst(DOMNode $parent, string $tag_name): DOMElement
{
$element = self::first($parent, $tag_name);
@@ -655,7 +648,7 @@ public static function expectFirst(DOMNode $parent, string $tag_name)
* @return string
* @throws XMLAssertException If there were no nodes with that tag name
*/
- public static function expectFirstText(DOMNode $parent, string $tag_name)
+ public static function expectFirstText(DOMNode $parent, string $tag_name): string
{
return self::text(self::expectFirst($parent, $tag_name));
}
@@ -668,7 +661,7 @@ public static function expectFirstText(DOMNode $parent, string $tag_name)
* @param string $tag_name
* @return DOMElement|null
*/
- public static function first(DOMNode $parent, string $tag_name)
+ public static function first(DOMNode $parent, string $tag_name): ?DOMElement
{
// Get the root element of a document first.
if ($parent instanceof DOMDocument) {
@@ -692,7 +685,7 @@ public static function first(DOMNode $parent, string $tag_name)
* @param string $tag_name
* @return string|null
*/
- public static function firstText(DOMNode $parent, string $tag_name)
+ public static function firstText(DOMNode $parent, string $tag_name): ?string
{
$element = self::first($parent, $tag_name);
if ($element === null) return null;
@@ -714,7 +707,7 @@ public static function firstText(DOMNode $parent, string $tag_name)
* @return DOMElement[] [name => element]
* @throws XMLAssertException If not all wanted tags are found
*/
- public static function gatherChildren(DOMNode $parent, array $wanted)
+ public static function gatherChildren(DOMNode $parent, array $wanted): array
{
$wanted = array_fill_keys($wanted, true);
$fetched = [];
@@ -761,7 +754,7 @@ public static function getChildrenText(DOMElement $node, string $tag): array
* @return DOMElement
* @throws XMLAssertException If no tag found
*/
- public static function expectOneOf(DOMNode $parent, array $wanted)
+ public static function expectOneOf(DOMNode $parent, array $wanted): DOMElement
{
foreach (self::getElementIterator($parent->childNodes) as $element) {
/** @var DOMElement $element */
@@ -780,7 +773,7 @@ public static function expectOneOf(DOMNode $parent, array $wanted)
* @param DOMNode $node
* @return string
*/
- public static function text(DOMNode $node)
+ public static function text(DOMNode $node): string
{
return trim($node->textContent);
}
@@ -793,7 +786,7 @@ public static function text(DOMNode $node)
* @param string $name
* @return string|null
*/
- public static function attr($element, string $name)
+ public static function attr(DOMDocument|DOMElement $element, string $name): ?string
{
if ($element instanceof DOMDocument) {
$element = $element->documentElement;
@@ -826,7 +819,7 @@ public static function toString(DOMNode $node): string
* @param DOMNode $node
* @return void echos
*/
- public static function print(DOMNode $node)
+ public static function print(DOMNode $node): void
{
/** @var DOMDocument */
$document = $node->ownerDocument ?? $node;
diff --git a/src/XMLException.php b/src/XMLException.php
index 945d586..8b3ef5d 100644
--- a/src/XMLException.php
+++ b/src/XMLException.php
@@ -17,5 +17,5 @@
class XMLException extends Exception
{
/** @var LibXMLError[] */
- public $errors = [];
+ public array $errors = [];
}
diff --git a/src/rules/AllInArrayRule.php b/src/rules/AllInArrayRule.php
index 273813d..251f037 100644
--- a/src/rules/AllInArrayRule.php
+++ b/src/rules/AllInArrayRule.php
@@ -19,11 +19,11 @@ class AllInArrayRule extends BaseRule
{
/** @var array */
- public $allowed = [];
+ public array $allowed = [];
/** @inheritdoc */
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
parent::parse($ruleset);
@@ -36,7 +36,7 @@ public function parse(array $ruleset)
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if (empty($this->allowed)) {
return;
diff --git a/src/rules/AllMatchRule.php b/src/rules/AllMatchRule.php
index fe4227c..93e3b9a 100644
--- a/src/rules/AllMatchRule.php
+++ b/src/rules/AllMatchRule.php
@@ -18,7 +18,7 @@ class AllMatchRule extends BaseRule
{
/** @inheritdoc */
- public function validate($data)
+ public function validate(array|object $data): void
{
$values = $this->getFieldValues($data);
$unique = array_unique($values);
diff --git a/src/rules/AllUniqueRule.php b/src/rules/AllUniqueRule.php
index 421e91d..cd9dcd0 100644
--- a/src/rules/AllUniqueRule.php
+++ b/src/rules/AllUniqueRule.php
@@ -18,7 +18,7 @@ class AllUniqueRule extends BaseRule
{
/** @inheritdoc */
- public function validate($data)
+ public function validate(array|object $data): void
{
$values = $this->getFieldValues($data);
$unique = array_unique($values);
diff --git a/src/rules/BinaryRule.php b/src/rules/BinaryRule.php
index bdf61a0..fed0d4e 100644
--- a/src/rules/BinaryRule.php
+++ b/src/rules/BinaryRule.php
@@ -18,7 +18,7 @@ class BinaryRule extends BaseRule
{
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if ($value !== '1' and $value !== 1 and $value !== '0' and $value !== 0) {
throw new ValidationException('Value must be a "1" or "0"');
diff --git a/src/rules/DateRangeRule.php b/src/rules/DateRangeRule.php
index e5639ea..636c086 100644
--- a/src/rules/DateRangeRule.php
+++ b/src/rules/DateRangeRule.php
@@ -18,15 +18,15 @@
class DateRangeRule extends BaseRule
{
- public $min = null;
+ public ?string $min = null;
- public $max = null;
+ public ?string $max = null;
- public $ordered = true;
+ public bool $ordered = true;
/** @inheritdoc */
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
parent::parse($ruleset);
@@ -44,7 +44,7 @@ public function parse(array $ruleset)
/** @inheritdoc */
- public function validate($data)
+ public function validate(array|object $data): void
{
if (count($this->fields) != 2) {
return;
diff --git a/src/rules/EmailRule.php b/src/rules/EmailRule.php
index 8cbe3af..3560788 100644
--- a/src/rules/EmailRule.php
+++ b/src/rules/EmailRule.php
@@ -21,7 +21,7 @@ class EmailRule extends BaseRule
{
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
$regex = '/^[^@]+@[^@.]+\.[^@]+$/iD';
diff --git a/src/rules/InArrayRule.php b/src/rules/InArrayRule.php
index bb50556..6d74872 100644
--- a/src/rules/InArrayRule.php
+++ b/src/rules/InArrayRule.php
@@ -19,11 +19,11 @@ class InArrayRule extends BaseRule
{
/** @var array */
- public $allowed = [];
+ public array $allowed = [];
/** @inheritdoc */
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
parent::parse($ruleset);
@@ -36,7 +36,7 @@ public function parse(array $ruleset)
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if (empty($this->allowed)) {
return;
diff --git a/src/rules/Ipv4AddrOrCidrRule.php b/src/rules/Ipv4AddrOrCidrRule.php
index 5a90b44..484fcca 100644
--- a/src/rules/Ipv4AddrOrCidrRule.php
+++ b/src/rules/Ipv4AddrOrCidrRule.php
@@ -17,7 +17,7 @@ class Ipv4AddrOrCidrRule extends BaseRule
{
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if (strpos($value, '/') === false) {
$rule = new Ipv4AddrRule();
diff --git a/src/rules/Ipv4AddrRule.php b/src/rules/Ipv4AddrRule.php
index cca2ef0..57ed388 100644
--- a/src/rules/Ipv4AddrRule.php
+++ b/src/rules/Ipv4AddrRule.php
@@ -18,7 +18,7 @@ class Ipv4AddrRule extends BaseRule
{
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if (!preg_match('/^[0-9]+(?:\.[0-9]+){3}$/', $value)) {
throw new ValidationException('Invalid IP address');
diff --git a/src/rules/Ipv4CidrRule.php b/src/rules/Ipv4CidrRule.php
index 69dfc45..9ce3996 100644
--- a/src/rules/Ipv4CidrRule.php
+++ b/src/rules/Ipv4CidrRule.php
@@ -18,7 +18,7 @@ class Ipv4CidrRule extends BaseRule
{
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if (strpos($value, '/') === false) {
throw new ValidationException('Invalid CIDR block');
diff --git a/src/rules/LengthRule.php b/src/rules/LengthRule.php
index 3399549..d7801cf 100644
--- a/src/rules/LengthRule.php
+++ b/src/rules/LengthRule.php
@@ -24,13 +24,13 @@
class LengthRule extends BaseRule
{
- public $min = 0;
+ public int $min = 0;
- public $max = PHP_INT_MAX;
+ public int $max = PHP_INT_MAX;
/** @inheritdoc */
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
parent::parse($ruleset);
@@ -40,7 +40,7 @@ public function parse(array $ruleset)
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
$len = mb_strlen($value);
diff --git a/src/rules/MysqlDateRule.php b/src/rules/MysqlDateRule.php
index f9a9ef0..b3b5c6d 100644
--- a/src/rules/MysqlDateRule.php
+++ b/src/rules/MysqlDateRule.php
@@ -25,7 +25,7 @@ public static function getName(): string
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
$matches = null;
if (!preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/', $value, $matches)) {
diff --git a/src/rules/MysqlDateTimeRule.php b/src/rules/MysqlDateTimeRule.php
index 7a78069..e6fa88b 100644
--- a/src/rules/MysqlDateTimeRule.php
+++ b/src/rules/MysqlDateTimeRule.php
@@ -25,7 +25,7 @@ public static function getName(): string
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
$matches = null;
if (!preg_match('/^([0-9]{4}-[0-9]{2}-[0-9]{2}) ([0-9]{2}:[0-9]{2}:[0-9]{2})$/', $value, $matches)) {
diff --git a/src/rules/MysqlTimeRule.php b/src/rules/MysqlTimeRule.php
index 46283b8..b05caff 100644
--- a/src/rules/MysqlTimeRule.php
+++ b/src/rules/MysqlTimeRule.php
@@ -25,7 +25,7 @@ public static function getName(): string
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
$matches = null;
if (!preg_match('/^([0-9]{2}):([0-9]{2}):([0-9]{2})$/', $value, $matches)) {
diff --git a/src/rules/NumericRule.php b/src/rules/NumericRule.php
index 8ce04b6..80ff61f 100644
--- a/src/rules/NumericRule.php
+++ b/src/rules/NumericRule.php
@@ -18,7 +18,7 @@ class NumericRule extends BaseRule
{
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if (!is_numeric($value)) {
throw new ValidationException('Value must be a number');
diff --git a/src/rules/OneRequiredRule.php b/src/rules/OneRequiredRule.php
index 1d4019a..502be88 100644
--- a/src/rules/OneRequiredRule.php
+++ b/src/rules/OneRequiredRule.php
@@ -17,9 +17,9 @@
class OneRequiredRule extends BaseRule
{
/** @var string|null */
- public $group;
+ public ?string $group = null;
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
parent::parse($ruleset);
@@ -28,7 +28,7 @@ public function parse(array $ruleset)
/** @inheritdoc */
- public function validate($data)
+ public function validate(array|object $data): void
{
$values = $this->getFieldValues($data);
diff --git a/src/rules/PasswordRule.php b/src/rules/PasswordRule.php
index c28a8ae..01bf70e 100644
--- a/src/rules/PasswordRule.php
+++ b/src/rules/PasswordRule.php
@@ -18,11 +18,11 @@ class PasswordRule extends BaseRule
{
- public $digits = 8;
+ public int $digits = 8;
/** @inheritdoc */
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
parent::parse($ruleset);
@@ -33,7 +33,7 @@ public function parse(array $ruleset)
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
$errors = [];
diff --git a/src/rules/PhoneRule.php b/src/rules/PhoneRule.php
index b5cc141..55ad52c 100644
--- a/src/rules/PhoneRule.php
+++ b/src/rules/PhoneRule.php
@@ -17,11 +17,11 @@
class PhoneRule extends BaseRule
{
- public $digits = 8;
+ public int $digits = 8;
/** @inheritdoc */
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
parent::parse($ruleset);
@@ -32,7 +32,7 @@ public function parse(array $ruleset)
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
// Allow international numbers starting with + and country code, e.g. +61 for Australia
$clean = preg_replace('/^\+[0-9]+ */', '', $value);
diff --git a/src/rules/PositiveIntRule.php b/src/rules/PositiveIntRule.php
index e2420b4..922319b 100644
--- a/src/rules/PositiveIntRule.php
+++ b/src/rules/PositiveIntRule.php
@@ -18,7 +18,7 @@ class PositiveIntRule extends BaseRule
{
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if (preg_match('/[^0-9]/', $value)) {
throw new ValidationException("Value must be a whole number that is greater than zero");
diff --git a/src/rules/ProseTextRule.php b/src/rules/ProseTextRule.php
index 4424eeb..47a7295 100644
--- a/src/rules/ProseTextRule.php
+++ b/src/rules/ProseTextRule.php
@@ -23,7 +23,7 @@ class ProseTextRule extends BaseRule
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
// pL = letters, pN = numbers
if (preg_match('/[^-\pL\pN \'"\/!?@#$%&():;.,]/u', (string) $value)) {
diff --git a/src/rules/RangeRule.php b/src/rules/RangeRule.php
index 5a534e8..4935067 100644
--- a/src/rules/RangeRule.php
+++ b/src/rules/RangeRule.php
@@ -18,13 +18,13 @@
class RangeRule extends BaseRule
{
- public $min = null;
+ public ?int $min = null;
- public $max = null;
+ public ?int $max = null;
/** @inheritdoc */
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
parent::parse($ruleset);
@@ -44,7 +44,7 @@ public function parse(array $ruleset)
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if (!is_numeric($value)) {
throw new ValidationException('Value must be a number');
diff --git a/src/rules/RegexRule.php b/src/rules/RegexRule.php
index c6698b2..e870e94 100644
--- a/src/rules/RegexRule.php
+++ b/src/rules/RegexRule.php
@@ -18,11 +18,11 @@
class RegexRule extends BaseRule
{
- public $pattern = null;
+ public ?string $pattern = null;
/** @inheritdoc */
- public function parse(array $ruleset)
+ public function parse(array $ruleset): void
{
parent::parse($ruleset);
@@ -35,7 +35,7 @@ public function parse(array $ruleset)
/** @inheritdoc */
- public function validateOne(string $field, $value)
+ public function validateOne(string $field, mixed $value): void
{
if (!$this->pattern) {
return;
diff --git a/src/rules/RequiredRule.php b/src/rules/RequiredRule.php
index 7bfef71..ded4f73 100644
--- a/src/rules/RequiredRule.php
+++ b/src/rules/RequiredRule.php
@@ -22,7 +22,7 @@ class RequiredRule extends BaseRule
{
/** @inheritdoc */
- public function validate($data)
+ public function validate(array|object $data): void
{
if (empty($this->fields)) {
return;
diff --git a/tests/EventTest.php b/tests/EventTest.php
index cbf43da..f21cd60 100644
--- a/tests/EventTest.php
+++ b/tests/EventTest.php
@@ -98,7 +98,7 @@ public function testPrepend()
Events::on(RootEmitter::class, function(TestEvent $event) {
$this->assertNull($event->sender);
return 'two';
- }, false);
+ }, append: false);
// Test parent class listener.
Events::on(RootEmitter::class, TestEvent::class, function(Event $event) {
@@ -131,15 +131,15 @@ public function testHandled()
Events::on(RootEmitter::class, function(TestEvent $event) {
$event->handled = true;
return 'three';
- }, false);
+ }, append: false);
Events::on(RootEmitter::class, function(TestEvent $event) {
return 'four';
- }, false);
+ }, append: false);
Events::on(RootEmitter::class, function(TestEvent $event) {
return 'five';
- }, true);
+ }, append: true);
$event = new TestEvent();
$actual = Events::trigger(RootEmitter::class, $event);