- Added support for closure in Virtual field

This commit is contained in:
Dave Mc Nicoll 2023-11-07 11:01:55 -05:00
parent 756474d460
commit a4b81f1932
2 changed files with 26 additions and 10 deletions

View File

@ -8,6 +8,14 @@ class Virtual extends Field {
public bool $readonly = true; public bool $readonly = true;
public function __construct( public function __construct(
public ? string $method = null, public null|string|array $method = null,
) {} public ? \Closure $closure = null,
) {
$this->method ??= [ static::class, 'noop' ];
}
public static function noop() : null
{
return null;
}
} }

View File

@ -78,11 +78,19 @@ class RelationBuilder
protected function resolveVirtual(string $name) : mixed protected function resolveVirtual(string $name) : mixed
{ {
if (null !== ($virtual = $this->resolver->searchFieldAnnotation($name, [ Attribute\Property\Virtual::class, Annotation\Property\Virtual::class ]))) { if (null !== ($virtual = $this->resolver->searchFieldAnnotation($name, [ Attribute\Property\Virtual::class, Annotation\Property\Virtual::class ]))) {
if ($virtual->closure ?? false) { try {
return call_user_func_array($virtual->closure, [ $this->entity ]); $arguments = [ $this->entity ];
}
return call_user_func_array([ $this->entity, $virtual->method ], [ $this->entity ]); if ($virtual->closure ?? false) {
return call_user_func_array($virtual->closure, $arguments);
}
elseif ($virtual->method ?? false) {
return call_user_func_array(is_array($virtual->method) ? $virtual->method : [$this->entity, $virtual->method], $arguments);
}
}
catch(\Throwable $e) {
throw new $e(sprintf("An error occurred while calling method from your #[Virtual] attribute in entity '%s::%s'.", $this->entity::class, $name ));
}
} }
return false; return false;
@ -115,7 +123,7 @@ class RelationBuilder
$this->entity->eventExecute(Event\EntityRelationLoadInterface::class, $name, $this->repository); $this->entity->eventExecute(Event\EntityRelationLoadInterface::class, $name, $this->repository);
return call_user_func([ $this->repository, $relation->function() ]); return call_user_func([ $this->repository, $relation->function() ]);
case $relation->isManyToMany(): case $relation->isManyToMany():
$this->manyToMany($name, $relation, $relationRelation); $this->manyToMany($name, $relation, $relationRelation);