From 89a7d0c05924127eabf68970ae1979ac0bcf6f65 Mon Sep 17 00:00:00 2001 From: Maxim Akimov Date: Fri, 20 Dec 2024 15:30:44 +0200 Subject: [PATCH 1/3] readme --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cb7192f..cda5e86 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,8 @@ WordPress. ### 5.3) Is the dot syntax in keys inspired by Laravel Collections? -Yes, the dot syntax is inspired by [Laravel Collections](https://laravel.com/docs/11.x/collections) and similar solutions. It provides an intuitive way to access +Yes, the dot syntax is inspired by [Laravel Collections](https://laravel.com/docs/11.x/collections) and similar +solutions. It provides an intuitive way to access nested data structures. ### 5.4) Why not just use Laravel Collections? @@ -160,11 +161,15 @@ nested data structures. Laravel Collections and similar libraries don’t offer type-specific methods like this package does. While extending -[Laravel Collections package](https://github.com/illuminate/collections) could be a theoretical solution, we opted for a standalone package because: +[Laravel Collections package](https://github.com/illuminate/collections) could be a theoretical solution, we opted for a +standalone package because: -1. PHP Version Requirements: Laravel Collections require PHP 8.2+, while Typed supports PHP 7.4+. -2. Dependencies: Laravel Collections bring several external Laravel-specific dependencies. -3. Global Functions: Laravel Collections rely on global helper functions, which are difficult to scope when needed. +1. **PHP Version Requirements:** Laravel Collections require PHP 8.2+, while Typed supports PHP 7.4+. +2. **Dependencies:** Laravel Collections bring several external Laravel-specific dependencies. +3. **Global Functions:** Laravel Collections rely on global helper functions, which are difficult to scope when needed. + +In addition, when we only need to extract a single variable, requiring the entire array to be wrapped in a collection +would be excessive. ## 6. Contribution From 1b3d30cbe87b66a4e8558eb9b20f004e3aef5578 Mon Sep 17 00:00:00 2001 From: Maxim Akimov Date: Fri, 20 Dec 2024 15:31:22 +0200 Subject: [PATCH 2/3] readme --- .github/{workflow => workflows}/tests.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{workflow => workflows}/tests.yaml (100%) diff --git a/.github/workflow/tests.yaml b/.github/workflows/tests.yaml similarity index 100% rename from .github/workflow/tests.yaml rename to .github/workflows/tests.yaml From 87ae8ffd0af4292ed4ad16cded55b96f6ea62026 Mon Sep 17 00:00:00 2001 From: Maxim Akimov Date: Fri, 20 Dec 2024 15:45:21 +0200 Subject: [PATCH 3/3] readme --- README.md | 3 +- src/Typed.php | 151 +++++++++++++++++++++++---------------- tests/Unit/TypedTest.php | 2 +- 3 files changed, 94 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index cda5e86..399b694 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,8 @@ Static methods for the following types are present: * `bool` * `array` * `object` -* `DateTime` +* `dateTime` +* `any` (allows to use short dot-keys usage for unknowns) For optional cases, each type has an `OrNull` method option (e.g. `stringOrNull`), which returns `null` if the key doesn’t exist. diff --git a/src/Typed.php b/src/Typed.php index fef971d..96f0812 100644 --- a/src/Typed.php +++ b/src/Typed.php @@ -16,52 +16,6 @@ */ final class Typed { - /** - * @param mixed $source - * @param int|string $key - * @param mixed $value - * - * @return mixed - */ - protected static function resolveKey($source, $key, &$value): bool - { - if (true === is_object($source) && - true === isset($source->{$key})) { - $value = $source->{$key}; - return true; - } - - if (true === is_array($source) && - true === isset($source[$key])) { - $value = $source[$key]; - return true; - } - - return false; - } - - /** - * @param mixed $source - * @param array $keys - * @param mixed $default - * @return mixed - */ - protected static function resolveKeys($source, array $keys, $default) - { - foreach ($keys as $key) { - $value = null; - - if (true === self::resolveKey($source, $key, $value)) { - $source = $value; - continue; - } - - return $default; - } - - return $source; - } - /** * @param mixed $source * @param int|string|null $key @@ -173,29 +127,52 @@ public static function floatOrNull($source, $key = null): ?float /** * @param mixed $source * @param int|string|null $key - * @param array $allowed + * @param array $positive + * @param array $negative */ - public static function bool($source, $key = null, bool $default = false, array $allowed = [true, 1, '1', 'on',]): bool - { + public static function bool( + $source, + $key = null, + bool $default = false, + array $positive = [true, 1, '1', 'on',], + array $negative = [false, 0, '0', 'off',] + ): bool { $value = self::any($source, $key, $default); - return true === in_array($value, $allowed, true) ? - $value : - $default; + if (true === in_array($value, $positive, true)) { + return true; + } + + if (true === in_array($value, $negative, true)) { + return false; + } + + return $default; } /** * @param mixed $source * @param int|string|null $key - * @param array $allowed + * @param array $positive + * @param array $negative */ - public static function boolOrNull($source, $key = null, array $allowed = [true, 1, '1', 'on',]): ?bool - { + public static function boolOrNull( + $source, + $key = null, + array $positive = [true, 1, '1', 'on',], + array $negative = [false, 0, '0', 'off',] + ): ?bool { $value = self::any($source, $key); - return true === in_array($value, $allowed, true) ? - $value : - null; + if (true === in_array($value, $positive, true)) { + return true; + } + + if (true === in_array($value, $negative, true)) { + return false; + } + + return null; } /** @@ -207,7 +184,7 @@ public static function strictBool($source, $key = null, bool $default = false): $value = self::any($source, $key, $default); return true === is_bool($value) ? - $source : + $value : $default; } @@ -220,13 +197,16 @@ public static function strictBoolOrNull($source, $key = null): ?bool $value = self::any($source, $key); return true === is_bool($value) ? - $source : + $value : null; } /** * @param mixed $source * @param int|string|null $key + * @param array $default + * + * @return array */ public static function array($source, $key = null, array $default = []): array { @@ -240,6 +220,8 @@ public static function array($source, $key = null, array $default = []): array /** * @param mixed $source * @param int|string|null $key + * + * @return array|null */ public static function arrayOrNull($source, $key = null): ?array { @@ -309,4 +291,53 @@ public static function dateTimeOrNull($source, $key = null): ?DateTime $value : null; } + + /** + * @param mixed $source + * @param int|string $key + * @param mixed $value + */ + protected static function resolveKey($source, $key, &$value): bool + { + if ( + true === is_object($source) && + true === isset($source->{$key}) + ) { + $value = $source->{$key}; + return true; + } + + if ( + true === is_array($source) && + true === isset($source[$key]) + ) { + $value = $source[$key]; + return true; + } + + return false; + } + + /** + * @param mixed $source + * @param array $keys + * @param mixed $default + * + * @return mixed + */ + protected static function resolveKeys($source, array $keys, $default) + { + foreach ($keys as $key) { + $value = null; + + if (true === self::resolveKey($source, $key, $value)) { + $source = $value; + continue; + } + + return $default; + } + + return $source; + } } diff --git a/tests/Unit/TypedTest.php b/tests/Unit/TypedTest.php index 873c2b7..46873db 100644 --- a/tests/Unit/TypedTest.php +++ b/tests/Unit/TypedTest.php @@ -3,8 +3,8 @@ namespace Tests\Unit; use PHPUnit\Framework\TestCase; -use WPLake\Typed\Typed; use stdClass; +use WPLake\Typed\Typed; class TypedTest extends TestCase {