Skip to content

Commit

Permalink
Refactor MagicPropertiesTrait (#337)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigrov authored May 22, 2024
1 parent 352e04d commit c5a5081
Showing 1 changed file with 48 additions and 27 deletions.
75 changes: 48 additions & 27 deletions src/Trait/MagicPropertiesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
/**
* Trait to define magic methods to access values of an ActiveRecord instance.
*
* @method array getOldAttributes()
* @see AbstractActiveRecord::getOldAttributes()
*
* @method mixed getOldAttribute(string $name)
* @see AbstractActiveRecord::getOldAttribute()
*
* @method array getRelatedRecords()
* @see AbstractActiveRecord::getRelatedRecords()
*
Expand Down Expand Up @@ -122,6 +128,10 @@ public function __unset(string $name): void
if ($this->hasAttribute($name)) {
unset($this->attributes[$name]);

if (property_exists($this, $name)) {
$this->$name = null;
}

if ($this->hasDependentRelations($name)) {
$this->resetDependentRelations($name);
}
Expand All @@ -142,14 +152,7 @@ public function __unset(string $name): void
public function __set(string $name, mixed $value): void
{
if ($this->hasAttribute($name)) {
if (
$this->hasDependentRelations($name)
&& (!array_key_exists($name, $this->attributes) || $this->attributes[$name] !== $value)
) {
$this->resetDependentRelations($name);
}

$this->attributes[$name] = $value;
$this->setAttributeInternal($name, $value);
return;
}

Expand All @@ -170,6 +173,10 @@ public function __set(string $name, mixed $value): void

public function getAttribute(string $name): mixed
{
if (property_exists($this, $name)) {
return get_object_vars($this)[$name] ?? null;
}

return $this->attributes[$name] ?? null;
}

Expand All @@ -192,37 +199,31 @@ public function hasAttribute(string $name): bool

public function isAttributeChanged(string $name, bool $identical = true): bool
{
if (isset($this->attributes[$name], $this->oldAttributes[$name])) {
return $this->attributes[$name] !== $this->oldAttributes[$name];
$hasOldAttribute = array_key_exists($name, $this->getOldAttributes());

if (!$hasOldAttribute) {
return property_exists($this, $name) && array_key_exists($name, get_object_vars($this))
|| array_key_exists($name, $this->attributes);
}

return isset($this->attributes[$name]) || isset($this->oldAttributes[$name]);
if (property_exists($this, $name)) {
return !array_key_exists($name, get_object_vars($this))
|| $this->getOldAttribute($name) !== $this->$name;
}

return !array_key_exists($name, $this->attributes)
|| $this->getOldAttribute($name) !== $this->attributes[$name];
}

public function setAttribute(string $name, mixed $value): void
{
if ($this->hasAttribute($name)) {
if (
$this->hasDependentRelations($name)
&& (!array_key_exists($name, $this->attributes) || $this->attributes[$name] !== $value)
) {
$this->resetDependentRelations($name);
}
$this->attributes[$name] = $value;
$this->setAttributeInternal($name, $value);
} else {
throw new InvalidArgumentException(static::class . ' has no attribute named "' . $name . '".');
}
}

protected function populateAttribute(string $name, mixed $value): void
{
if (property_exists($this, $name)) {
$this->$name = $value;
} else {
$this->attributes[$name] = $value;
}
}

/**
* Returns a value indicating whether a property is defined for this component.
*
Expand Down Expand Up @@ -263,4 +264,24 @@ public function canSetProperty(string $name, bool $checkVars = true): bool
|| ($checkVars && property_exists($this, $name))
|| $this->hasAttribute($name);
}

protected function populateAttribute(string $name, mixed $value): void
{
if (property_exists($this, $name)) {
$this->$name = $value;
} else {
$this->attributes[$name] = $value;
}
}

private function setAttributeInternal(string $name, mixed $value): void
{
if ($this->hasDependentRelations($name)
&& ($value === null || $this->getAttribute($name) !== $value)
) {
$this->resetDependentRelations($name);
}

$this->populateAttribute($name, $value);
}
}

0 comments on commit c5a5081

Please sign in to comment.