Files
CABM-IT/app/Models/FlexibleAssetField.php
T
jeremy bayse 8f22dca9c8 Initial commit: CABM-IT (ItGlue-style MSP documentation platform)
Laravel 13 + Livewire/Volt app for managing client organizations,
documents, passwords, flexible assets, virtual machines, contacts,
domains, todos, shortcuts, and role-based user administration.
2026-08-16 13:28:12 +02:00

81 lines
2.5 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
#[Fillable([
'flexible_asset_type_id', 'name', 'label', 'field_type',
'options', 'is_required', 'show_in_list', 'sort_order',
])]
class FlexibleAssetField extends Model
{
const FIELD_TYPES = ['text', 'textarea', 'password', 'checkbox', 'date', 'tag', 'select', 'related_asset'];
/**
* Built-in record lists a "related_asset" field can point to.
* Keys are stored in options.target; values map to an Organization relation
* name and the attribute used as the display label.
*/
const RELATED_TARGETS = [
'contact' => ['relation' => 'contacts', 'label' => 'full_name'],
'location' => ['relation' => 'locations', 'label' => 'name'],
'domain' => ['relation' => 'domains', 'label' => 'name'],
];
protected function casts(): array
{
return [
'options' => 'array',
'is_required' => 'boolean',
'show_in_list' => 'boolean',
];
}
public function type()
{
return $this->belongsTo(FlexibleAssetType::class, 'flexible_asset_type_id');
}
public function relatedTarget(): ?string
{
return $this->options['target'] ?? null;
}
/**
* Records available for this field's related_asset target, scoped to the organization.
* @return Collection<int, array{id: int, label: string}>
*/
public function relatedOptions(Organization $organization): Collection
{
$target = $this->relatedTarget();
if (! $target) {
return collect();
}
if (str_starts_with($target, 'flexible_asset:')) {
$typeId = (int) substr($target, strlen('flexible_asset:'));
return $organization->flexibleAssets()
->where('flexible_asset_type_id', $typeId)
->orderBy('name')
->get()
->map(fn (FlexibleAsset $asset) => ['id' => $asset->id, 'label' => $asset->name]);
}
$config = self::RELATED_TARGETS[$target] ?? null;
if (! $config) {
return collect();
}
return $organization->{$config['relation']}()
->orderBy($config['label'] === 'full_name' ? 'last_name' : $config['label'])
->get()
->map(fn (Model $record) => ['id' => $record->id, 'label' => (string) $record->{$config['label']}]);
}
}