Skip to content
This repository has been archived by the owner on Mar 30, 2022. It is now read-only.

Commit

Permalink
Adds object_assign and shadow helpers.
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkGhostHunter committed Sep 2, 2021
1 parent b3c3d5c commit d1061cd
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 56 deletions.
48 changes: 36 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ This package includes helpful global helpers for your project make almost anythi

| | | |
|---|---|---|
| [app_call](#app_call) | [in_console](#in_console) | [route_is](#route_is)
| [call_existing](#call_existing) | [in_development](#in_development) | [sleep_between](#sleep_between)
| [created](#created) | [logged_in](#logged_in) | [taptap](#taptap)
| [data_update](#data_update) | [methods_of](#methods_of) | [undot_path](#undot_path)
| [delist](#delist) | [missing_trait](#missing_trait) | [until](#until)
| [diff](#diff) | [none_of](#none_of) | [user](#user)
| [dot_path](#dot_path) | [ok](#ok) | [weekend](#weekend)
| [enclose](#enclose) | [period](#period) | [weekstart](#weekstart)
| [files](#files) | [period_from](#period_from) | [which_of](#which_of)
| [has_trait](#has_trait) | [pipe](#pipe) | [yesterday](#yesterday)
| [hashy](#hashy) | [remember](#remember) |

| [app_call](#app_call) | [in_development](#in_development) | [route_is](#route_is)
| [call_existing](#call_existing) | [logged_in](#logged_in) | [shadow](#shadow)
| [created](#created) | [methods_of](#methods_of) | [sleep_between](#sleep_between)
| [data_update](#data_update) | [missing_trait](#missing_trait) | [taptap](#taptap)
| [delist](#delist) | [none_of](#none_of) | [undot_path](#undot_path)
| [diff](#diff) | [object_assign](#object_assign) | [until](#until)
| [dot_path](#dot_path) | [ok](#ok) | [user](#user)
| [enclose](#enclose) | [period](#period) | [weekend](#weekend)
| [files](#files) | [period_from](#period_from) | [weekstart](#weekstart)
| [has_trait](#has_trait) | [pipe](#pipe) | [which_of](#which_of)
| [hashy](#hashy) | [remember](#remember) | [yesterday](#yesterday)
| [in_console](#in_console) | [route_is](#route_is) |
### `app_call()`

Executes a callable using the application Container.
Expand Down Expand Up @@ -320,6 +320,18 @@ none_of('foo', ['bar', 'baz', 'qux'], fn ($subject, $compared) => $subject === $
// false
```

### `object_assign()`

Assigns an array of values to an object, recursively, using dot notation.

```php
$object = new stdClass();

object_assign($object, ['foo' => 'bar']);

echo $object->foo; // "bar"
```

### `ok()`

Returns an HTTP 204 response (OK, No Content).
Expand Down Expand Up @@ -439,6 +451,18 @@ if (route_is('dahsboard.*')) {
}
```

### `shadow()`

Calls a method on an object if it exists, or returns false. It supports Macros.

```php
if ($rendered = shadow($mayRender, 'render')) {
return $rendered;
}

return response((string)$mayRender);
```

### `sleep_between()`

Runs a callback while sleeping between multiple executions, returning a Collection of all results.
Expand Down
79 changes: 62 additions & 17 deletions helpers/common.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Pipeline\Pipeline;
use Illuminate\Support\Collection;
use Illuminate\Support\Stringable as LaravelStringable;
Expand Down Expand Up @@ -59,6 +60,23 @@ function enclose(mixed $value): Closure
}
}

if (!function_exists('hashy')) {
/**
* Creates a small BASE64 encoded MD5 hash from a string for portable checksum.
*
* @param \Stringable|\Illuminate\Support\Stringable|string $hashable
* @param string|null $hash The hash to compare the result.
*
* @return string|bool Returns a boolean if a comparable hash has been set to compare.
*/
function hashy(Stringable|LaravelStringable|string $hashable, string $hash = null): string|bool
{
$hashed = base64_encode(md5((string)$hashable, true));

return $hash ? hash_equals($hash, $hashed) : $hashed;
}
}

if (!function_exists('in_console')) {
/**
* Check if the application is running in console.
Expand Down Expand Up @@ -115,6 +133,30 @@ function none_of(mixed $subject, iterable $options, callable $callback = null):
}
}

if (!function_exists('object_assign')) {
/**
* Assigns an array of values to an object, recursively, using dot notation.
*
* @param object $object
* @param \Illuminate\Contracts\Support\Arrayable|iterable $data
* @param bool $overwrite
*
* @return object
*/
function object_assign(object $object, Arrayable|iterable $data, bool $overwrite = true): object
{
if ($data instanceof Arrayable) {
$data = $data->toArray();
}

foreach ($data as $name => $value) {
data_set($object, $name, $value, $overwrite);
}

return $object;
}
}

if (!function_exists('pipe')) {
/**
* Sends an object through a pipeline.
Expand Down Expand Up @@ -167,6 +209,26 @@ function remember(
}
}

if (!function_exists('shadow')) {
/**
* Calls a method on an object if it exists, or returns false.
*
* @param object $object
* @param string $method
* @param mixed ...$arguments
*
* @return mixed
*/
function shadow(object $object, string $method, mixed ...$arguments): mixed
{
if (method_exists($object, $method) || method_exists($object, 'hasMacro') && $object::hasMacro($method)) {
return $object->{$method}(...$arguments);
}

return false;
}
}

if (!function_exists('sleep_between')) {
/**
* Runs a callback while sleeping between multiple executions.
Expand Down Expand Up @@ -209,23 +271,6 @@ function taptap(mixed $value, callable $callback = null): mixed
}
}

if (!function_exists('hashy')) {
/**
* Creates a small BASE64 encoded MD5 hash from a string for portable checksum.
*
* @param \Stringable|\Illuminate\Support\Stringable|string $hashable
* @param string|null $hash The hash to compare the result.
*
* @return string|bool Returns a boolean if a comparable hash has been set to compare.
*/
function hashy(Stringable|LaravelStringable|string $hashable, string $hash = null): string|bool
{
$hashed = base64_encode(md5((string)$hashable, true));

return $hash ? hash_equals($hash, $hashed) : $hashed;
}
}

if (!function_exists('which_of')) {
/**
* Returns the key of the option which comparison or callback returns true.
Expand Down
97 changes: 70 additions & 27 deletions tests/CommonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

use Closure;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Fluent;
use Illuminate\Support\HigherOrderTapProxy;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Macroable;
use Orchestra\Testbench\TestCase;
use Stringable;

Expand Down Expand Up @@ -124,6 +126,25 @@ public function test(): string
static::assertSame('bar.quz', $enclose('bar'));
}

public function test_hashy(): void
{
$hashable = 'This is a hashable string';
$expected = 'TJYa8+63dRbdN6w44shX1g==';

static::assertSame($expected, hashy($hashable));
static::assertSame($expected, hashy(Str::of($hashable)));
static::assertSame($expected, hashy(new class implements Stringable {
public function __toString(): string
{
return 'This is a hashable string';
}
}));

static::assertTrue(hashy($hashable, $expected));
static::assertFalse(hashy($hashable, $expected . '='));
static::assertFalse(hashy($hashable, 'TJYa8+63dRbdN6w44shX1g='));
}

public function test_in_console(): void
{
static::assertTrue(in_console());
Expand Down Expand Up @@ -186,6 +207,24 @@ public function test_none_of(): void
}));
}

public function test_object_assign()
{
$object = new class extends Fluent {};

$array = ['foo' => 'bar', 'baz' => 'quz'];
static::assertSame($object, object_assign($object, $array));
static::assertSame('bar', $object->foo);

$arrayable = new class(['baz' => 'cougar', 'qux' => 'quuz']) extends Fluent {};
static::assertSame($object, object_assign($object, $arrayable));
static::assertSame('cougar', $object->baz);
static::assertSame('quuz', $object->qux);

$array = ['qux' => 'quux'];
static::assertSame($object, object_assign($object, $array, false));
static::assertSame('quuz', $object->qux);
}

public function test_pipe(): void
{
$barToQuz = new class {
Expand Down Expand Up @@ -222,17 +261,27 @@ static function (string $foo, Closure $next): string {
static::assertSame('qux', $pipe);
}

public function test_while_sleep(): void
public function test_shadow(): void
{
$start = time();
$collection = sleep_between(4, 1000, static function (): string {
return microtime(false);
$object = new class {
public function foo($string) {
return $string;
}
};

static::assertSame('bar', shadow($object, 'foo', 'bar'));
static::assertFalse(shadow($object, 'bar', 'bar'));

$object = new class {
use Macroable;
};

$object::macro('bar', function ($string) {
return $string;
});
$end = time();

static::assertCount(4, $collection);
static::assertGreaterThanOrEqual(3, $end - $start);
static::assertLessThan(5, $end - $start);
static::assertSame('foo', shadow($object, 'bar', 'foo'));
static::assertFalse(shadow($object, 'foo', 'bar'));
}

public function test_taptap(): void
Expand All @@ -256,25 +305,6 @@ public function call(): bool {
static::assertTrue($object->called);
}

public function test_hashy(): void
{
$hashable = 'This is a hashable string';
$expected = 'TJYa8+63dRbdN6w44shX1g==';

static::assertSame($expected, hashy($hashable));
static::assertSame($expected, hashy(Str::of($hashable)));
static::assertSame($expected, hashy(new class implements Stringable {
public function __toString(): string
{
return 'This is a hashable string';
}
}));

static::assertTrue(hashy($hashable, $expected));
static::assertFalse(hashy($hashable, $expected . '='));
static::assertFalse(hashy($hashable, 'TJYa8+63dRbdN6w44shX1g='));
}

public function test_which_of(): void
{
static::assertSame(3, which_of('foo', ['bar', 'quz', 'qux', 'foo']));
Expand All @@ -300,4 +330,17 @@ public function test_which_of(): void
}
}));
}

public function test_while_sleep(): void
{
$start = time();
$collection = sleep_between(4, 1000, static function (): string {
return microtime(false);
});
$end = time();

static::assertCount(4, $collection);
static::assertGreaterThanOrEqual(3, $end - $start);
static::assertLessThan(5, $end - $start);
}
}

0 comments on commit d1061cd

Please sign in to comment.