Files
postshop-backend/nova-components/InlineRelationship/src/InlineRelationship.php
2026-02-03 15:31:29 +05:00

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(),
]);
}
}