Files
fotospiel-app/app/Models/TaskCollection.php
Codex Agent 750acb0bec
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Allow task attach search across global tasks
2026-01-19 21:42:09 +01:00

139 lines
3.4 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
class TaskCollection extends Model
{
use HasFactory;
protected $table = 'task_collections';
protected $fillable = [
'tenant_id',
'slug',
'name_translations',
'description_translations',
'event_type_id',
'source_collection_id',
'is_default',
'position',
];
protected $casts = [
'name_translations' => 'array',
'description_translations' => 'array',
];
public function eventType(): BelongsTo
{
return $this->belongsTo(EventType::class);
}
public function tenant(): BelongsTo
{
return $this->belongsTo(Tenant::class);
}
public function sourceCollection(): BelongsTo
{
return $this->belongsTo(TaskCollection::class, 'source_collection_id');
}
public function derivedCollections(): HasMany
{
return $this->hasMany(TaskCollection::class, 'source_collection_id');
}
public function tasks(): BelongsToMany
{
return $this->belongsToMany(
Task::class,
'task_collection_task',
'task_collection_id',
'task_id'
)->withPivot(['sort_order']);
}
public function events(): BelongsToMany
{
return $this->belongsToMany(
Event::class,
'event_task_collection',
'task_collection_id',
'event_id'
)->withPivot(['sort_order'])->withTimestamps();
}
public function scopeGlobal($query)
{
return $query->whereNull('tenant_id');
}
public function scopeForTenant($query, ?int $tenantId)
{
return $query->where(function ($inner) use ($tenantId) {
$inner->whereNull('tenant_id');
if ($tenantId) {
$inner->orWhere('tenant_id', $tenantId);
}
});
}
public function getNameAttribute(): string
{
return $this->resolveTranslation('name_translations');
}
public function getDescriptionAttribute(): ?string
{
$value = $this->resolveTranslation('description_translations');
return $value ?: null;
}
/**
* @param array<int, int|string> $taskIds
*/
public function reassignTasks(array $taskIds): void
{
$ids = array_values(array_unique(array_map('intval', $taskIds)));
if ($ids === []) {
return;
}
DB::table('task_collection_task')
->whereIn('task_id', $ids)
->where('task_collection_id', '!=', $this->getKey())
->delete();
Task::query()
->whereIn('id', $ids)
->update(['collection_id' => $this->getKey()]);
}
protected function resolveTranslation(string $attribute, ?string $locale = null): string
{
$translations = $this->{$attribute} ?? [];
if (is_string($translations)) {
$translations = json_decode($translations, true) ?: [];
}
$locale = $locale ?? app()->getLocale();
return $translations[$locale]
?? Arr::first($translations)
?? '';
}
}