Skip to content

Commit

Permalink
Entity->hasValue() should not set null value for uninitialized proper…
Browse files Browse the repository at this point in the history
…ty (#514)

* tests: fix log dir when simply run with debugger

* relationship: do not require dummy setRawValue init call for non-main OneHasOne relationship

* entity: hasValue() should not set null value for uninitialized property

Co-authored-by: Jan Skrasek <[email protected]>
  • Loading branch information
hrach authored Apr 15, 2021
2 parents 7a55112 + 1200d20 commit bcf9743
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/Entity/ImmutableDataTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private function &internalGetValue(PropertyMetadata $metadata, string $name)
private function internalHasValue(PropertyMetadata $metadata, string $name): bool
{
if (!isset($this->validated[$name])) {
$this->initProperty($metadata, $name);
$this->initProperty($metadata, $name, false);
}

if ($this->data[$name] instanceof IPropertyContainer) {
Expand Down
8 changes: 2 additions & 6 deletions src/Relationships/HasOne.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use Nextras\Orm\Exception\InvalidArgumentException;
use Nextras\Orm\Exception\InvalidStateException;
use Nextras\Orm\Exception\NullValueException;
use Nextras\Orm\Mapper\IRelationshipMapper;
use Nextras\Orm\Repository\IRepository;
use function assert;

Expand All @@ -36,10 +35,10 @@ abstract class HasOne implements IRelationshipContainer
*/
protected $collection;

/** @var bool */
/** @var bool Is value validated against storage? */
protected $isValueValidated = true;

/** @var bool */
/** @var bool Is raw value loaded from storage and not converted yet? */
protected $isValueFromStorage = false;

/** @var IEntity|string|int|null */
Expand All @@ -57,9 +56,6 @@ abstract class HasOne implements IRelationshipContainer
/** @var bool */
protected $isModified = false;

/** @var IRelationshipMapper */
protected $relationshipMapper;


public function __construct(PropertyMetadata $metadata)
{
Expand Down
12 changes: 10 additions & 2 deletions src/Relationships/OneHasOne.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@

use Nextras\Orm\Collection\ICollection;
use Nextras\Orm\Entity\IEntity;
use Nextras\Orm\Entity\Reflection\PropertyMetadata;
use function assert;


class OneHasOne extends HasOne
{
public function __construct(PropertyMetadata $metadata)
{
parent::__construct($metadata);
$this->isValueFromStorage = !$this->metadataRelationship->isMain;
}


/** {@inheritDoc} */
protected function createCollection(): ICollection
{
Expand All @@ -29,7 +37,7 @@ public function setRawValue($value): void

public function getRawValue()
{
if (!$this->isValueValidated && !$this->metadataRelationship->isMain) {
if ($this->isValueFromStorage && !$this->metadataRelationship->isMain) {
$this->initValue();
}
return parent::getRawValue();
Expand All @@ -38,7 +46,7 @@ public function getRawValue()

public function hasInjectedValue(): bool
{
if (!$this->isValueValidated && !$this->metadataRelationship->isMain) {
if ($this->isValueFromStorage && !$this->metadataRelationship->isMain) {
$this->initValue();
}
return parent::hasInjectedValue();
Expand Down
21 changes: 21 additions & 0 deletions tests/cases/integration/Entity/entity.hasValue().phpt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
namespace NextrasTests\Orm\Integration\Entity;


use Nextras\Orm\Entity\AbstractEntity;
use Nextras\Orm\Entity\Reflection\EntityMetadata;
use Nextras\Orm\Model\MetadataStorage;
use NextrasTests\Orm\Author;
use NextrasTests\Orm\DataTestCase;
use NextrasTests\Orm\Ean;
use Tester\Assert;


Expand All @@ -28,6 +32,23 @@ class EntityHasValueTest extends DataTestCase
Assert::false($author->hasValue('name'));
Assert::true($author->hasValue('web'));
Assert::true($author->hasValue('age'));

// avoid default ean constructor not to set the default type
$ean = new class extends Ean {
/** @noinspection PhpMissingParentConstructorInspection */
// @phpstan-ignore-next-line
public function __construct()
{
AbstractEntity::__construct();
}


protected function createMetadata(): EntityMetadata
{
return MetadataStorage::get(Ean::class);
}
};
Assert::false($ean->hasValue('type'));
}

}
Expand Down
13 changes: 13 additions & 0 deletions tests/cases/integration/Relationships/relationships.oneHasOne.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,19 @@ class RelationshipOneHasOneTest extends DataTestCase
$bookId = $ean->getRawValue('book');
Assert::equal(1, $bookId);
}


public function testHasValue(): void
{
$ean = new Ean();
$ean->code = '1234';
$ean->book = $this->orm->books->getByIdChecked(1);
$this->orm->eans->persistAndFlush($ean);
$this->orm->clear();

$ean = $this->orm->eans->getByChecked(['code' => '1234']);
Assert::true($ean->hasValue('book'));
}
}


Expand Down
2 changes: 1 addition & 1 deletion tests/inc/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ protected function setUp()
$configurator = new Configurator();

if (!Helper::isRunByRunner()) {
$configurator->enableDebugger(__DIR__ . '/log');
$configurator->enableDebugger(__DIR__ . '/../log');
}

$hashData = json_encode($dbConfig);
Expand Down
2 changes: 1 addition & 1 deletion tests/inc/model/ean/Ean.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* @property Book $book {1:1 Book::$ean}
* @property EanType $type {wrapper TestEnumPropertyWrapper}
*/
final class Ean extends Entity
class Ean extends Entity
{
public function __construct(EanType $type = null)
{
Expand Down

0 comments on commit bcf9743

Please sign in to comment.