|
<?php |
|
|
|
namespace App\Utils; |
|
|
|
use Illuminate\Database\Eloquent\Relations\Relation; |
|
use Illuminate\Support\Str; |
|
|
|
trait EasyRelations |
|
{ |
|
protected function getDefinedRelations() |
|
{ |
|
return $this->easyRelations ?? []; |
|
} |
|
|
|
public function isRelation($key) |
|
{ |
|
return parent::isRelation($key) || $this->getEasyRelation($key); |
|
} |
|
|
|
public function getEasyRelation($key) |
|
{ |
|
$relations = collect($this->getDefinedRelations()) |
|
->mapWithKeys(function ($relation, $class) { |
|
$key = Str::endsWith($relation, 'Many') ? Str::plural(class_basename($class)) : class_basename($class); |
|
return [Str::kebab($key) => ['model' => $class, 'type' => $relation]]; |
|
})->toArray(); |
|
|
|
$key = Str::kebab($key); |
|
|
|
if (!array_key_exists($key, $relations)) { |
|
return null; |
|
} |
|
|
|
return $relations[$key]; |
|
} |
|
|
|
|
|
public function getRelationValue($key) |
|
{ |
|
$definition = $this->getEasyRelation($key); |
|
|
|
if (is_null($definition)) { |
|
return parent::getRelationValue($key); |
|
} |
|
|
|
$relation = $this->createRelationObject($key, $definition); |
|
|
|
return tap($relation->getResults(), function ($results) use ($key) { |
|
$this->setRelation($key, $results); |
|
}); |
|
} |
|
|
|
public function relationResolver($class, $key) |
|
{ |
|
$resolver = parent::relationResolver($class, $key); |
|
|
|
if (!is_null($resolver)) { |
|
return $resolver; |
|
} |
|
|
|
$definition = $this->getEasyRelation($key); |
|
|
|
if (is_null($definition)) { |
|
return null; |
|
} |
|
|
|
|
|
return fn() => $this->createRelationObject($key, $definition); |
|
} |
|
|
|
public function createRelationObject($key, $definition): Relation |
|
{ |
|
return match ($definition['type']) { |
|
'belongsTo' => $this->belongsTo($definition['model'], null, null, $key), |
|
'morphMany' => $this->morphMany($definition['model'], Str::singular($key) . 'able'), |
|
'hasMany' => $this->hasMany($definition['model']), |
|
default => null, // TODO: support other relation types |
|
}; |
|
} |
|
} |