116 lines
2.9 KiB
PHP
116 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace Nurmuhammet\InlineRelationship;
|
|
|
|
use Exception;
|
|
use Laravel\Nova\Fields\Field;
|
|
use Laravel\Nova\Fields\SupportsDependentFields;
|
|
|
|
class InlineRelationship extends Field
|
|
{
|
|
use SupportsDependentFields;
|
|
|
|
/**
|
|
* The field's component.
|
|
*
|
|
* @var string
|
|
*/
|
|
public $component = 'inline-relationship';
|
|
|
|
/**
|
|
* Related resource name
|
|
*/
|
|
protected string $relatedResourceName;
|
|
|
|
/**
|
|
* Resource relationship attribute to related resource
|
|
*/
|
|
protected string $relationshipAttribute;
|
|
|
|
/**
|
|
* Related resource
|
|
*/
|
|
protected string $relatedResource;
|
|
|
|
/**
|
|
* Relationship type
|
|
*/
|
|
protected string $relationshipType;
|
|
|
|
/**
|
|
* Create a new field.
|
|
*
|
|
* @param string|null $attribute
|
|
* @param class-string<\Laravel\Nova\Resource>|null $resource
|
|
* @return void
|
|
*/
|
|
public function __construct(string $name, string $attribute, string $resource)
|
|
{
|
|
parent::__construct($name, $attribute);
|
|
|
|
$this->relatedResourceName = $name;
|
|
$this->relationshipAttribute = $attribute;
|
|
$this->relatedResource = $resource;
|
|
$this->relatedResourceURI = $resource::uriKey();
|
|
$this->relationshipType = $this->guessRelationshipType();
|
|
|
|
$this->validate();
|
|
|
|
$this->fullWidth();
|
|
$this->transformDataForFrontend();
|
|
}
|
|
|
|
/**
|
|
* Validate user's arguments
|
|
*/
|
|
public function validate(): void
|
|
{
|
|
in_array($this->relationshipType, $this->allowedRelationships())
|
|
? true
|
|
: throw new Exception("Selected relationship ({$relationshipType}) is not allowed");
|
|
}
|
|
|
|
/**
|
|
* Alloed relationships
|
|
*/
|
|
public function allowedRelationships(): array
|
|
{
|
|
return [
|
|
'Illuminate\\Database\\Eloquent\\Relations\\HasMany',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Guess relationship type from related resource
|
|
*/
|
|
public function guessRelationshipType(): string
|
|
{
|
|
return get_class((new $this->relatedResource::$model)->{$this->relationshipAttribute}());
|
|
}
|
|
|
|
/**
|
|
* Formatted relationship name
|
|
*/
|
|
public function formattedRelatioshipName(): string
|
|
{
|
|
return match ($this->relationshipType) {
|
|
'Illuminate\\Database\\Eloquent\\Relations\\HasMany' => 'hasMany',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Transform data to frontend
|
|
*/
|
|
public function transformDataForFrontend(): self
|
|
{
|
|
return $this->withMeta([
|
|
'singularLabel' => $this->relatedResource::singularLabel(),
|
|
'relatedResourceName' => $this->relatedResourceName,
|
|
'relationshipAttribute' => $this->relationshipAttribute,
|
|
'relatedResource' => $this->relatedResource,
|
|
'relatedResourceURI' => $this->relatedResourceURI,
|
|
'relationshipType' => $this->formattedRelatioshipName(),
|
|
]);
|
|
}
|
|
}
|