Skip to content

Commit

Permalink
1. NestedHelper renamed to NestedAccess.
Browse files Browse the repository at this point in the history
2. `NestedHelper` is deprecated.
  • Loading branch information
Smoren committed Jan 12, 2023
1 parent 5320ee0 commit 6aa01f6
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 140 deletions.
113 changes: 113 additions & 0 deletions src/Helpers/NestedAccess.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php

namespace Smoren\NestedAccessor\Helpers;

use Smoren\NestedAccessor\Components\NestedAccessor;
use Smoren\NestedAccessor\Exceptions\NestedAccessorException;

/**
* Helper for getting and setting to source array or object with nested keys
* @author Smoren <ofigate@gmail.com>
*/
class NestedAccess
{
/**
* @var NestedAccessor|null nested accessor instance
*/
protected static ?NestedAccessor $accessor = null;

/**
* Gets value from nested source by given path
* @param array<scalar, mixed>|object $source source
* @param string|array<string> $path path e.g. 'path.to.value' or ['path', 'to', 'value']
* @param bool $strict if true: throw exception when path is not found in source
* @return mixed value got by path
* @throws NestedAccessorException
*/
public static function get($source, $path, bool $strict = true)
{
return static::prepareAccessor($source)->get($path, $strict);
}

/**
* Sets value to nested source by given path
* @param array<scalar, mixed>|object $source source
* @param string|array<string> $path path e.g. 'path.to.value' or ['path', 'to', 'value']
* @param mixed $value value to set
* @param bool $strict if true: throw exception when path is not found in source
* @return void
* @throws NestedAccessorException
*/
public static function set(&$source, $path, $value, bool $strict = true): void
{
static::prepareAccessor($source)->set($path, $value, $strict);
}

/**
* Appends value to nested source by given path
* @param array<scalar, mixed>|object $source source
* @param string|array<string> $path path e.g. 'path.to.value' or ['path', 'to', 'value']
* @param mixed $value value to set
* @param bool $strict if true: throw exception when path is not found in source
* @return void
* @throws NestedAccessorException
*/
public static function append(&$source, $path, $value, bool $strict = true): void
{
static::prepareAccessor($source)->append($path, $value, $strict);
}

/**
* Deletes value to nested source by given path
* @param array<scalar, mixed>|object $source source
* @param string|array<string> $path path e.g. 'path.to.value' or ['path', 'to', 'value']
* @param bool $strict if true: throw exception when path is not found in source
* @return void
* @throws NestedAccessorException
*/
public static function delete(&$source, $path, bool $strict = true): void
{
static::prepareAccessor($source)->delete($path, $strict);
}

/**
* Returns true if path exists, false otherwise
* @param array<scalar, mixed>|object $source source
* @param string|string[] $path nested path
* @return bool
* @throws NestedAccessorException
*/
public static function exist(&$source, $path): bool
{
return static::prepareAccessor($source)->exist($path);
}

/**
* Returns true if path exists and not null, false otherwise
* @param array<scalar, mixed>|object $source source
* @param string|string[] $path nested path
* @return bool
* @throws NestedAccessorException
*/
public static function isset(&$source, $path): bool
{
return static::prepareAccessor($source)->isset($path);
}

/**
* Method for preparing accessor to use with source
* @param array<scalar, mixed>|object $source source data
* @return NestedAccessor
* @throws NestedAccessorException
*/
protected static function prepareAccessor(&$source): NestedAccessor
{
if(static::$accessor === null) {
static::$accessor = new NestedAccessor($source);
} else {
static::$accessor->setSource($source);
}

return static::$accessor;
}
}
108 changes: 3 additions & 105 deletions src/Helpers/NestedHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,112 +2,10 @@

namespace Smoren\NestedAccessor\Helpers;

use Smoren\NestedAccessor\Components\NestedAccessor;
use Smoren\NestedAccessor\Exceptions\NestedAccessorException;

/**
* Helper for getting and setting to source array or object with nested keys
* @author Smoren <ofigate@gmail.com>
* @deprecated use NestedAccess
* @see NestedAccess
*/
class NestedHelper
class NestedHelper extends NestedAccess
{
/**
* @var NestedAccessor|null nested accessor instance
*/
protected static ?NestedAccessor $accessor = null;

/**
* Gets value from nested source by given path
* @param array<scalar, mixed>|object $source source
* @param string|array<string> $path path e.g. 'path.to.value' or ['path', 'to', 'value']
* @param bool $strict if true: throw exception when path is not found in source
* @return mixed value got by path
* @throws NestedAccessorException
*/
public static function get($source, $path, bool $strict = true)
{
return static::prepareAccessor($source)->get($path, $strict);
}

/**
* Sets value to nested source by given path
* @param array<scalar, mixed>|object $source source
* @param string|array<string> $path path e.g. 'path.to.value' or ['path', 'to', 'value']
* @param mixed $value value to set
* @param bool $strict if true: throw exception when path is not found in source
* @return void
* @throws NestedAccessorException
*/
public static function set(&$source, $path, $value, bool $strict = true): void
{
static::prepareAccessor($source)->set($path, $value, $strict);
}

/**
* Appends value to nested source by given path
* @param array<scalar, mixed>|object $source source
* @param string|array<string> $path path e.g. 'path.to.value' or ['path', 'to', 'value']
* @param mixed $value value to set
* @param bool $strict if true: throw exception when path is not found in source
* @return void
* @throws NestedAccessorException
*/
public static function append(&$source, $path, $value, bool $strict = true): void
{
static::prepareAccessor($source)->append($path, $value, $strict);
}

/**
* Deletes value to nested source by given path
* @param array<scalar, mixed>|object $source source
* @param string|array<string> $path path e.g. 'path.to.value' or ['path', 'to', 'value']
* @param bool $strict if true: throw exception when path is not found in source
* @return void
* @throws NestedAccessorException
*/
public static function delete(&$source, $path, bool $strict = true): void
{
static::prepareAccessor($source)->delete($path, $strict);
}

/**
* Returns true if path exists, false otherwise
* @param array<scalar, mixed>|object $source source
* @param string|string[] $path nested path
* @return bool
* @throws NestedAccessorException
*/
public static function exist(&$source, $path): bool
{
return static::prepareAccessor($source)->exist($path);
}

/**
* Returns true if path exists and not null, false otherwise
* @param array<scalar, mixed>|object $source source
* @param string|string[] $path nested path
* @return bool
* @throws NestedAccessorException
*/
public static function isset(&$source, $path): bool
{
return static::prepareAccessor($source)->isset($path);
}

/**
* Method for preparing accessor to use with source
* @param array<scalar, mixed>|object $source source data
* @return NestedAccessor
* @throws NestedAccessorException
*/
protected static function prepareAccessor(&$source): NestedAccessor
{
if(static::$accessor === null) {
static::$accessor = new NestedAccessor($source);
} else {
static::$accessor->setSource($source);
}

return static::$accessor;
}
}
70 changes: 35 additions & 35 deletions tests/unit/NestedHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Smoren\NestedAccessor\Tests\Unit;

use Smoren\NestedAccessor\Exceptions\NestedAccessorException;
use Smoren\NestedAccessor\Helpers\NestedHelper;
use Smoren\NestedAccessor\Helpers\NestedAccess;

class NestedHelperTest extends \Codeception\Test\Unit
{
Expand All @@ -16,21 +16,21 @@ public function testSimple()
$source = [
'a' => ['b' => [['c' => 1], ['c' => 2]]],
];
$this->assertEquals([1, 2], NestedHelper::get($source, ['a', 'b', 'c']));
NestedHelper::set($source, ['a', 'd'], 22);
$this->assertEquals([1, 2], NestedHelper::get($source, ['a', 'b', 'c']));
$this->assertEquals(22, NestedHelper::get($source, ['a', 'd']));
$this->assertEquals([1, 2], NestedAccess::get($source, ['a', 'b', 'c']));
NestedAccess::set($source, ['a', 'd'], 22);
$this->assertEquals([1, 2], NestedAccess::get($source, ['a', 'b', 'c']));
$this->assertEquals(22, NestedAccess::get($source, ['a', 'd']));

$source = [
'test' => ['value' => 123],
];
$this->assertEquals(123, NestedHelper::get($source, ['test', 'value']));
$this->assertEquals(123, NestedHelper::get($source, 'test.value'));
$this->assertEquals(null, NestedHelper::get($source, 'unknown.value', false));
$this->assertEquals(123, NestedAccess::get($source, ['test', 'value']));
$this->assertEquals(123, NestedAccess::get($source, 'test.value'));
$this->assertEquals(null, NestedAccess::get($source, 'unknown.value', false));

$source = ['test' => [1, 2]];
NestedHelper::append($source, ['test'], 3);
$this->assertEquals([1, 2, 3], NestedHelper::get($source, ['test']));
NestedAccess::append($source, ['test'], 3);
$this->assertEquals([1, 2, 3], NestedAccess::get($source, ['test']));
}

/**
Expand All @@ -43,13 +43,13 @@ public function testExist()
'test' => ['a' => 1, 'b' => null, 'null' => 2],
'null' => 3,
];
$this->assertTrue(NestedHelper::exist($source, 'test.a'));
$this->assertTrue(NestedHelper::exist($source, 'test.b'));
$this->assertTrue(NestedHelper::exist($source, 'test.null'));
$this->assertTrue(NestedHelper::exist($source, 'null'));
$this->assertFalse(NestedHelper::exist($source, 'test.a.b'));
$this->assertFalse(NestedHelper::exist($source, 'test.c'));
$this->assertFalse(NestedHelper::exist($source, 'null.c'));
$this->assertTrue(NestedAccess::exist($source, 'test.a'));
$this->assertTrue(NestedAccess::exist($source, 'test.b'));
$this->assertTrue(NestedAccess::exist($source, 'test.null'));
$this->assertTrue(NestedAccess::exist($source, 'null'));
$this->assertFalse(NestedAccess::exist($source, 'test.a.b'));
$this->assertFalse(NestedAccess::exist($source, 'test.c'));
$this->assertFalse(NestedAccess::exist($source, 'null.c'));
}

/**
Expand All @@ -62,13 +62,13 @@ public function testIsset()
'test' => ['a' => 1, 'b' => null, 'null' => 2],
'null' => 3,
];
$this->assertTrue(NestedHelper::isset($source, 'test.a'));
$this->assertFalse(NestedHelper::isset($source, 'test.b'));
$this->assertTrue(NestedHelper::isset($source, 'test.null'));
$this->assertTrue(NestedHelper::isset($source, 'null'));
$this->assertFalse(NestedHelper::isset($source, 'test.a.b'));
$this->assertFalse(NestedHelper::isset($source, 'test.c'));
$this->assertFalse(NestedHelper::isset($source, 'null.c'));
$this->assertTrue(NestedAccess::isset($source, 'test.a'));
$this->assertFalse(NestedAccess::isset($source, 'test.b'));
$this->assertTrue(NestedAccess::isset($source, 'test.null'));
$this->assertTrue(NestedAccess::isset($source, 'null'));
$this->assertFalse(NestedAccess::isset($source, 'test.a.b'));
$this->assertFalse(NestedAccess::isset($source, 'test.c'));
$this->assertFalse(NestedAccess::isset($source, 'null.c'));
}

/**
Expand All @@ -82,26 +82,26 @@ public function testDelete()
'null' => 3,
];

$this->assertEquals(['a' => 1, 'b' => null, 'null' => 2], NestedHelper::get($source, 'test'));
NestedHelper::delete($source, 'test.a');
$this->assertEquals(['b' => null, 'null' => 2], NestedHelper::get($source, 'test'));
$this->assertEquals(['a' => 1, 'b' => null, 'null' => 2], NestedAccess::get($source, 'test'));
NestedAccess::delete($source, 'test.a');
$this->assertEquals(['b' => null, 'null' => 2], NestedAccess::get($source, 'test'));

NestedHelper::delete($source, 'test.b');
$this->assertEquals(['null' => 2], NestedHelper::get($source, 'test'));
NestedAccess::delete($source, 'test.b');
$this->assertEquals(['null' => 2], NestedAccess::get($source, 'test'));

NestedHelper::delete($source, 'test');
$this->assertEquals(['null' => 3], NestedHelper::get($source, ''));
NestedAccess::delete($source, 'test');
$this->assertEquals(['null' => 3], NestedAccess::get($source, ''));

try {
NestedHelper::delete($source, 'test');
NestedAccess::delete($source, 'test');
$this->fail();
} catch(NestedAccessorException $e) {
$this->assertEquals(NestedAccessorException::CANNOT_DELETE_VALUE, $e->getCode());
$this->assertEquals('test', $e->getData()['path']);
}
$this->assertEquals(['null' => 3], NestedHelper::get($source, ''));
$this->assertEquals(['null' => 3], NestedAccess::get($source, ''));

NestedHelper::delete($source, 'test', false);
$this->assertEquals(['null' => 3], NestedHelper::get($source, ''));
NestedAccess::delete($source, 'test', false);
$this->assertEquals(['null' => 3], NestedAccess::get($source, ''));
}
}

0 comments on commit 6aa01f6

Please sign in to comment.