110 lines
3.3 KiB
PHP
110 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Models\Subscription;
|
|
use App\Models\CalendarInstance;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
use Illuminate\Database\Eloquent\Relations\HasOne;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
class Calendar extends Model
|
|
{
|
|
protected $table = 'calendars'; // Sabre table
|
|
public $timestamps = false; // no created_at/updated_at
|
|
|
|
/* add mass-assignment for these cols */
|
|
protected $fillable = [
|
|
'synctoken',
|
|
'components',
|
|
];
|
|
|
|
/* all event components (VEVENT, VTODO, …) */
|
|
public function events(): HasMany
|
|
{
|
|
return $this->hasMany(Event::class, 'calendarid'); // FK in calendarobjects
|
|
}
|
|
|
|
/* ui-specific metadata (color, sharing flags, json settings) */
|
|
public function meta(): HasOne
|
|
{
|
|
return $this->hasOne(CalendarMeta::class, 'calendar_id');
|
|
}
|
|
|
|
/* get instances */
|
|
public function instances()
|
|
{
|
|
return $this->hasMany(CalendarInstance::class, 'calendarid');
|
|
}
|
|
|
|
/* get the primary? instance for a user */
|
|
public function instanceForUser(?User $user = null): CalendarInstance
|
|
{
|
|
$user = $user ?? auth()->user();
|
|
|
|
return $this->instances()
|
|
->where('principaluri', $user->principal_uri)
|
|
->first();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* build all calendar data for calendar display
|
|
*/
|
|
public function scopeDashboardForPrincipal(Builder $q, string $principal): Builder
|
|
{
|
|
return $q->select(
|
|
'calendars.id',
|
|
'ci.displayname',
|
|
'ci.calendarcolor',
|
|
'ci.uri as slug',
|
|
'ci.timezone as timezone',
|
|
'meta.color as meta_color',
|
|
'meta.color_fg as meta_color_fg',
|
|
DB::raw('COALESCE(meta.is_remote, 0) as is_remote')
|
|
)
|
|
->join('calendarinstances as ci', 'ci.calendarid', '=', 'calendars.id')
|
|
->leftJoin('calendar_meta as meta', 'meta.calendar_id', '=', 'calendars.id')
|
|
->where('ci.principaluri', $principal)
|
|
->orderBy('ci.displayname');
|
|
}
|
|
|
|
/**
|
|
*
|
|
* inbound urls
|
|
* convert "/calendar/{slug}" into the correct calendar instance (uri column)
|
|
*
|
|
* @param mixed $value The URI segment (instance UUID).
|
|
* @param string|null $field Ignored in our override.
|
|
*/
|
|
public function resolveRouteBinding($value, $field = null): mixed
|
|
{
|
|
$user = Auth::user();
|
|
|
|
return $this->newQuery()
|
|
->whereHas('instances', function (Builder $q) use ($value, $user) {
|
|
$q->where('uri', $value)
|
|
->where('principaluri', $user->principal_uri);
|
|
})
|
|
->with(['instances' => function ($q) use ($user) {
|
|
$q->where('principaluri', $user->principal_uri);
|
|
}])
|
|
->firstOrFail();
|
|
}
|
|
/**
|
|
* outbound urls
|
|
*/
|
|
public function getRouteKey(): string
|
|
{
|
|
// use the per-user instance slug for URLs; fall back to id if not available
|
|
$instance = $this->instances()
|
|
->where('principaluri', Auth::user()->principal_uri)
|
|
->first();
|
|
|
|
return $instance->uri ?? (string) $this->getKey();
|
|
}
|
|
}
|