Files
KanbanGit/app/Models/Project.php
T
Nico Schröder 3122e00ed8
linter / quality (pull_request) Successful in 2m52s
tests / ci (8.4) (pull_request) Successful in 3m15s
fix: make project template inheritance granular and safe
2026-09-08 12:03:07 +02:00

133 lines
3.5 KiB
PHP

<?php
namespace App\Models;
use Database\Factories\ProjectFactory;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Support\Str;
#[Fillable(['name', 'key', 'project_template_id', 'show_author', 'show_story_points', 'template_overrides'])]
class Project extends Model
{
/** @use HasFactory<ProjectFactory> */
use HasFactory;
protected function casts(): array
{
return [
'show_author' => 'boolean',
'show_story_points' => 'boolean',
'template_overrides' => 'array',
];
}
protected static function booted(): void
{
static::deleting(function (self $project): void {
$project->permissionAssignments()->delete();
});
}
protected function key(): Attribute
{
return Attribute::make(
set: fn (string $value): string => Str::upper(trim($value)),
);
}
public function permissionAssignments(): MorphMany
{
return $this->morphMany(PermissionAssignment::class, 'scope');
}
public function projectTemplate(): BelongsTo
{
return $this->belongsTo(ProjectTemplate::class, 'project_template_id');
}
public function baseTemplate(): HasOne
{
return $this->hasOne(ProjectTemplate::class)
->where('is_published', false);
}
public function boardColumns(): HasMany
{
return $this->hasMany(BoardColumn::class)
->orderBy('position');
}
public function ticketFieldDefinitions(): HasMany
{
return $this->hasMany(TicketFieldDefinition::class)
->orderBy('position');
}
public function ticketPriorities(): HasMany
{
return $this->hasMany(TicketPriority::class)
->orderBy('position');
}
public function ticketLinkTypes(): HasMany
{
return $this->hasMany(TicketLinkType::class)
->orderBy('position');
}
public function ticketStatuses(): HasMany
{
return $this->hasMany(TicketStatus::class)
->orderBy('board_column_id')
->orderBy('position');
}
public function ticketTypes(): HasMany
{
return $this->hasMany(TicketType::class)
->orderBy('position');
}
public function repositoryConnections(): HasMany
{
return $this->hasMany(RepositoryConnection::class)
->orderBy('provider')
->orderBy('repository_full_name');
}
public function notificationActions(): HasMany
{
return $this->hasMany(NotificationAction::class)
->orderBy('name')
->orderBy('id');
}
/** @return list<string> */
public function configurationRelations(): array
{
return [
'boardColumns',
'notificationActions',
'repositoryConnections',
'ticketFieldDefinitions',
'ticketLinkTypes',
'ticketPriorities',
'ticketStatuses',
'ticketTypes',
];
}
public function tickets(): HasMany
{
return $this->hasMany(Ticket::class)
->orderByDesc('sequence_number');
}
}