Skip to content

Commit

Permalink
Merge pull request #61 from sroehrl/computed-values
Browse files Browse the repository at this point in the history
Enhance model via computed values
  • Loading branch information
sroehrl authored Jan 22, 2023
2 parents a45fca9 + 1f1a2d4 commit f7b84b5
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 138 deletions.
10 changes: 10 additions & 0 deletions src/Helper/AttributeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class AttributeHelper
public array $propertyMatchList = [];
private array $parsedClass = [];

public array $attributeMethods = [];

/**
* @throws ReflectionException
*/
Expand All @@ -38,9 +40,17 @@ private function generateMachLists(): void
$this->propertyMatchList[$property->getName()] = $attributes;
foreach ($attributes as $attribute) {
$this->attributeMatchList[$attribute->getName()][] = $property->getName();
}
}
foreach ($this->methods as $method) {
$attributes = $method->getAttributes();
foreach ($attributes as $attribute){
$instance = $attribute->newInstance();

$this->attributeMethods[$attribute->getName()][] = [$instance, $method->getName()];
}
}

}

public function findConstant(string $constant): ?string
Expand Down
30 changes: 30 additions & 0 deletions src/Model/Attributes/Computed.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Neoan\Model\Attributes;

use Attribute;
use Neoan\Enums\AttributeType;
use Neoan\Model\Interfaces\ModelAttribute;
use Neoan\Model\Model;

#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_ALL)]
class Computed implements ModelAttribute
{
public mixed $initial;

public function __construct(mixed $initial = null)
{
$this->initial = $initial;
}

function __invoke(Model &$currentModel, string $method)
{
$currentModel->{$method} = $currentModel->{$method}($this->initial);

}

public function getType(): AttributeType
{
return AttributeType::PRIVATE;
}
}
28 changes: 27 additions & 1 deletion src/Model/Interpreter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Neoan\Helper\AttributeHelper;
use Neoan\Helper\Str;
use Neoan\Model\Attributes\IsPrimaryKey;
use Playground\Debug;
use ReflectionException;
use ReflectionProperty;
use TypeError;
Expand Down Expand Up @@ -67,6 +66,12 @@ public function initialize(array $staticModel = []): Model
// initialization attributes
$this->executeAttributes($property['attributes'], $property['name'], AttributeType::INITIAL, Direction::IN);
}
foreach($this->reflection->attributeMethods as $methods){
foreach ($methods as $method){
$method[0]($this->currentModel, $method[1]);
}

}
return $this->currentModel;
}

Expand Down Expand Up @@ -168,4 +173,25 @@ public function getPrimaryKey(): string
return $this->reflection->findPropertiesByAttribute(IsPrimaryKey::class)[0] ?? 'id';
}

public function removePrivateAttributes(Model &$instance) : void
{
foreach ($this->reflection->properties as $property){
foreach ($property->getAttributes() as $attribute){
if($attribute->newInstance()->getType() === AttributeType::PRIVATE && $property->isPublic() && !$property->isReadOnly()) {
unset($instance->{$property->getName()});
}

}

}
foreach($this->reflection->attributeMethods as $methods){
foreach ($methods as $method){
if(isset($method[1])){
unset($instance->{$method[1]});
}
}

}
}

}
1 change: 1 addition & 0 deletions src/Model/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public function store(): static
self::interpret();
$modelClass = get_called_class();
$copy = new $modelClass($this->toArray(true));
self::$interpreter->removePrivateAttributes($copy);
$insertOrUpdate = self::$interpreter->generateInsertUpdate($copy);

$id = null;
Expand Down
9 changes: 8 additions & 1 deletion tests/Mocks/MockModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Test\Mocks;

use Neoan\Database\Database;
use Neoan\Model\Attributes\Computed;
use Neoan\Model\Attributes\HasMany;
use Neoan\Model\Attributes\Ignore;
use Neoan\Model\Attributes\IsPrimaryKey;
Expand Down Expand Up @@ -34,7 +35,7 @@ class MockModel extends Model
public Collection $attached;

#[Ignore]
private bool $hasBeenStored = false;
public bool $hasBeenStored = false;

function called(): bool
{
Expand All @@ -46,6 +47,12 @@ public function afterStore(): void
$this->hasBeenStored = true;
}

#[Computed]
public function virtual(): string
{
return 'computed value';
}

function ensure(): self
{
Database::raw('
Expand Down
6 changes: 6 additions & 0 deletions tests/Model/AttributeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Neoan\Enums\TimePeriod;
use Neoan\Helper\AttributeHelper;
use Neoan\Helper\DateHelper;
use Neoan\Model\Attributes\Computed;
use Neoan\Model\Attributes\HasMany;
use Neoan\Model\Attributes\Ignore;
use Neoan\Model\Attributes\Initialize;
Expand Down Expand Up @@ -50,6 +51,11 @@ function testHasMany()
$result = $attribute(1, 'different');
$this->assertSame('anotherId', $result['notId']);
}
function testComputed()
{
$attribute = new Computed();
$this->assertSame(AttributeType::PRIVATE, $attribute->getType());
}
function testFindAttributesByProperty()
{
$helper = new AttributeHelper(MockModel::class);
Expand Down
Loading

0 comments on commit f7b84b5

Please sign in to comment.