fix: Entity's isset() and unset()

This commit is contained in:
kenjis 2021-12-24 15:04:49 +09:00
parent 833c67f10a
commit c94219f4e5
No known key found for this signature in database
GPG Key ID: BD254878922AF198
2 changed files with 102 additions and 19 deletions

View File

@ -284,8 +284,8 @@ class Entity implements JsonSerializable
}
/**
* Checks the datamap to see if this column name is being mapped,
* and returns the mapped name, if any, or the original name.
* Checks the datamap to see if this property name is being mapped,
* and returns the db column name, if any, or the original property name.
*
* @return mixed|string
*/
@ -510,6 +510,10 @@ class Entity implements JsonSerializable
*/
public function __isset(string $key): bool
{
if ($this->isMappedDbColumn($key)) {
return false;
}
$key = $this->mapProperty($key);
$method = 'get' . str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $key)));
@ -526,6 +530,37 @@ class Entity implements JsonSerializable
*/
public function __unset(string $key): void
{
if ($this->isMappedDbColumn($key)) {
return;
}
$key = $this->mapProperty($key);
unset($this->attributes[$key]);
}
/**
* Whether this key is mapped db column name?
*/
protected function isMappedDbColumn(string $key): bool
{
$maybeColumnName = $this->mapProperty($key);
// Property name which has mapped column name
if (($key !== $maybeColumnName)) {
return false;
}
return $this->hasMappedProperty($key);
}
/**
* Whether this key has mapped property?
*/
protected function hasMappedProperty(string $key): bool
{
$property = array_search($key, $this->datamap, true);
return $property !== false;
}
}

View File

@ -120,12 +120,14 @@ final class EntityTest extends CIUnitTestCase
$entity->bar = 'made it';
// Check mapped field
// Check db column name
$this->assertSame('made it', $entity->foo);
// Should also get from original name
// since Model's would be looking for the original name
// Should also get from property name
// since Model's would be looking for the property name
$this->assertSame('made it', $entity->bar);
// But it shouldn't actually set a class property for the original name...
// But it shouldn't actually set a class property for the column name...
$this->expectException(ReflectionException::class);
$this->getPrivateProperty($entity, 'bar');
}
@ -134,7 +136,7 @@ final class EntityTest extends CIUnitTestCase
{
$entity = $this->getMappedEntity();
// Will map to "simple"
// Will map to "simple" column
$entity->orig = 'first';
$this->assertSame('oo:first:oo', $entity->simple);
@ -148,31 +150,36 @@ final class EntityTest extends CIUnitTestCase
{
$entity = $this->getMappedEntity();
// maps to 'foo'
// maps to 'foo' column
$entity->bar = 'here';
$attributes = $this->getPrivateProperty($entity, 'attributes');
$this->assertArrayHasKey('foo', $attributes);
$this->assertArrayNotHasKey('bar', $attributes);
$isset = isset($entity->bar);
$this->assertTrue($isset);
$isset = isset($entity->foo);
$this->assertFalse($isset);
}
public function testUnsetWorksWithMapping()
{
$entity = $this->getMappedEntity();
// maps to 'foo'
// maps to 'foo' column
$entity->bar = 'here';
// doesn't work on original name
unset($entity->bar);
// doesn't work on db column name
unset($entity->foo);
$this->assertSame('here', $entity->bar);
$this->assertSame('here', $entity->foo);
// does work on mapped field
unset($entity->foo);
// does work on property name
unset($entity->bar);
$this->assertNull($entity->foo);
$this->assertNull($entity->bar);
$isset = isset($entity->foo);
$this->assertFalse($isset);
$isset = isset($entity->bar);
$this->assertFalse($isset);
}
public function testDateMutationFromString()
@ -757,6 +764,29 @@ final class EntityTest extends CIUnitTestCase
], $result);
}
public function testSwapped()
{
$entity = $this->getSimpleSwappedEntity();
$entity->foo = '111';
$entity->bar = '222';
$isset = isset($entity->foo);
$this->assertTrue($isset);
$this->assertSame('111', $entity->foo);
$isset = isset($entity->bar);
$this->assertTrue($isset);
$this->assertSame('222', $entity->bar);
$result = $entity->toRawArray();
$this->assertSame([
'foo' => '222',
'bar' => '111',
], $result);
}
public function testToArraySkipAttributesWithUnderscoreInFirstCharacter()
{
$entity = new class () extends Entity {
@ -972,7 +1002,7 @@ final class EntityTest extends CIUnitTestCase
'simple' => null,
];
// 'bar' is db column, 'foo' is internal representation
// 'bar' is class property, 'foo' is db column
protected $datamap = [
'bar' => 'foo',
'orig' => 'simple',
@ -1009,6 +1039,24 @@ final class EntityTest extends CIUnitTestCase
};
}
protected function getSimpleSwappedEntity()
{
return new class () extends Entity {
protected $attributes = [
'foo' => 'foo',
'bar' => 'bar',
];
protected $_original = [
'foo' => 'foo',
'bar' => 'bar',
];
protected $datamap = [
'bar' => 'foo',
'foo' => 'bar',
];
};
}
protected function getCastEntity($data = null): Entity
{
return new class ($data) extends Entity {