105 lines
3.5 KiB
PHP
105 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace Ulmus\Attribute\Property;
|
|
|
|
use Ulmus\Attribute\Attribute;
|
|
use Ulmus\Repository;
|
|
|
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
|
class Relation implements ResettablePropertyInterface {
|
|
public function __construct(
|
|
public Relation\RelationTypeEnum|string $type,
|
|
public \Stringable|string|array $key = "",
|
|
public null|\Closure|array $generateKey = null,
|
|
public null|\Stringable|string|array $foreignKey = null,
|
|
public null|\Stringable|string|array $foreignField = null,
|
|
public array $foreignKeys = [],
|
|
public null|string $bridge = null,
|
|
public null|\Stringable|string|array $bridgeKey = null,
|
|
public null|\Stringable|string|array $bridgeField = null,
|
|
public null|\Stringable|string|array $bridgeForeignKey = null,
|
|
public null|\Stringable|string|array $field = null,
|
|
public null|string $entity = null,
|
|
public null|string $join = null,
|
|
public null|string $function = null,
|
|
public null|string $alias = null,
|
|
) {
|
|
$this->key = Attribute::handleArrayField($this->key);
|
|
$this->foreignKey = Attribute::handleArrayField($this->foreignKey);
|
|
$this->foreignField = Attribute::handleArrayField($this->foreignField);
|
|
$this->bridgeKey = Attribute::handleArrayField($this->bridgeKey);
|
|
$this->bridgeField = Attribute::handleArrayField($this->bridgeField);
|
|
$this->bridgeForeignKey = Attribute::handleArrayField($this->bridgeForeignKey);
|
|
$this->field = Attribute::handleArrayField($this->field);
|
|
}
|
|
|
|
public function entity() {
|
|
try {
|
|
$e = $this->entity;
|
|
} catch (\Throwable $ex) {
|
|
throw new \Exception("Your @Relation attribute seems to be missing an `entity` entry.");
|
|
}
|
|
|
|
return new $e();
|
|
}
|
|
|
|
public function bridge() {
|
|
$e = $this->bridge;
|
|
|
|
return new $e();
|
|
}
|
|
|
|
public function normalizeType() : string
|
|
{
|
|
return strtolower(str_replace(['-', '_', ' '], '', $this->type));
|
|
}
|
|
|
|
public function isOneToOne() : bool
|
|
{
|
|
return $this->type instanceof Relation\RelationTypeEnum ? $this->type === Relation\RelationTypeEnum::oneToOne : $this->normalizeType() === 'onetoone';
|
|
}
|
|
|
|
public function isOneToMany() : bool
|
|
{
|
|
return $this->type instanceof Relation\RelationTypeEnum ? $this->type === Relation\RelationTypeEnum::oneToMany : $this->normalizeType() === 'onetomany';
|
|
}
|
|
|
|
public function isManyToMany() : bool
|
|
{
|
|
return $this->type instanceof Relation\RelationTypeEnum ? $this->type === Relation\RelationTypeEnum::manyToMany : $this->normalizeType() === 'manytomany';
|
|
}
|
|
|
|
public function function() : string
|
|
{
|
|
if ($this->function) {
|
|
return $this->function;
|
|
}
|
|
elseif ($this->isOneToOne()) {
|
|
return 'loadOne';
|
|
}
|
|
|
|
return 'loadAll';
|
|
}
|
|
|
|
public function hasBridge() : bool
|
|
{
|
|
return (bool) $this->bridge;
|
|
}
|
|
|
|
## AWAITING THE Closures in constant expression from PHP 8.5 !
|
|
public function foreignKey(? Repository $repository = null) : mixed
|
|
{
|
|
if (is_string($this->foreignKey)) {
|
|
if (str_starts_with($this->foreignKey, 'fn(') && str_contains($this->foreignKey, '=>')) {
|
|
$closure = eval("return {$this->foreignKey};");
|
|
|
|
return $repository ? $closure($repository) : $closure;
|
|
}
|
|
|
|
return $this->entity::field($this->foreignKey, $this->alias);
|
|
}
|
|
|
|
return $this->foreignKey;
|
|
}
|
|
}
|