Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
18 changes: 12 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -152,19 +153,24 @@ 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?

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

Expand Down
151 changes: 91 additions & 60 deletions src/Typed.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<int,int|string> $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
Expand Down Expand Up @@ -173,29 +127,52 @@ public static function floatOrNull($source, $key = null): ?float
/**
* @param mixed $source
* @param int|string|null $key
* @param array<int|string,mixed> $allowed
* @param array<int|string,mixed> $positive
* @param array<int|string,mixed> $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<int|string,mixed> $allowed
* @param array<int|string,mixed> $positive
* @param array<int|string,mixed> $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;
}

/**
Expand All @@ -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;
}

Expand All @@ -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<int|string,mixed> $default
*
* @return array<int|string,mixed>
*/
public static function array($source, $key = null, array $default = []): array
{
Expand All @@ -240,6 +220,8 @@ public static function array($source, $key = null, array $default = []): array
/**
* @param mixed $source
* @param int|string|null $key
*
* @return array<int|string,mixed>|null
*/
public static function arrayOrNull($source, $key = null): ?array
{
Expand Down Expand Up @@ -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<int,int|string> $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;
}
}
2 changes: 1 addition & 1 deletion tests/Unit/TypedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down