171 lines
4.9 KiB
PHP
171 lines
4.9 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers;
|
||
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Str;
|
||
use Illuminate\Support\Facades\DB;
|
||
use App\Models\Calendar;
|
||
use App\Models\CalendarMeta;
|
||
|
||
class CalendarController extends Controller
|
||
{
|
||
/**
|
||
* list calendars owned by the logged-in user
|
||
*/
|
||
public function index()
|
||
{
|
||
$principal = 'principals/' . auth()->id();
|
||
|
||
$calendars = Calendar::query()
|
||
->select('calendars.*', 'ci.displayname as instance_displayname') // ← add
|
||
->join('calendarinstances as ci', 'ci.calendarid', '=', 'calendars.id')
|
||
->where('ci.principaluri', $principal)
|
||
->orderBy('ci.displayname')
|
||
->with(['meta']) // no need to eager-load full instances any more
|
||
->get();
|
||
|
||
return view('calendars.index', compact('calendars'));
|
||
}
|
||
|
||
public function create()
|
||
{
|
||
return view('calendars.create');
|
||
}
|
||
|
||
/**
|
||
* create sabre calendar + meta
|
||
*/
|
||
public function store(Request $request)
|
||
{
|
||
$data = $request->validate([
|
||
'name' => 'required|string|max:100',
|
||
'description' => 'nullable|string|max:255',
|
||
'timezone' => 'required|string',
|
||
'color' => 'nullable|regex:/^#[0-9A-Fa-f]{6}$/',
|
||
]);
|
||
|
||
// update master calendar entry
|
||
$calId = DB::table('calendars')->insertGetId([
|
||
'synctoken' => 1,
|
||
'components' => 'VEVENT', // or 'VEVENT,VTODO' if you add tasks
|
||
]);
|
||
|
||
// update the calendar instance row
|
||
$instance = CalendarInstance::create([
|
||
'calendarid' => $calId,
|
||
'principaluri' => 'principals/'.auth()->id(),
|
||
'uri' => Str::uuid(),
|
||
'displayname' => $data['name'],
|
||
'description' => $data['description'] ?? null,
|
||
'calendarcolor'=> $data['color'] ?? null,
|
||
'timezone' => $data['timezone'],
|
||
]);
|
||
|
||
// update calendar meta
|
||
$instance->meta()->create([
|
||
'calendar_id' => $instanceId,
|
||
'color' => $data['color'] ?? null,
|
||
'created_at' => now(),
|
||
'updated_at' => now(),
|
||
]);
|
||
|
||
return redirect()->route('calendars.index');
|
||
}
|
||
|
||
/**
|
||
* show calendar details
|
||
*/
|
||
public function show(Calendar $calendar)
|
||
{
|
||
$this->authorize('view', $calendar);
|
||
|
||
$calendar->load([
|
||
'meta',
|
||
'instances' => fn ($q) =>
|
||
$q->where('principaluri', 'principals/'.auth()->id()),
|
||
]);
|
||
|
||
/* grab the single instance for convenience in the view */
|
||
$instance = $calendar->instances->first();
|
||
$caldavUrl = $instance?->caldavUrl(); // null-safe
|
||
|
||
|
||
/* events + meta, newest first */
|
||
$events = $calendar->events()
|
||
->with('meta')
|
||
->orderByDesc('lastmodified')
|
||
->get();
|
||
|
||
return view(
|
||
'calendars.show',
|
||
compact('calendar', 'instance', 'events', 'caldavUrl')
|
||
);
|
||
}
|
||
|
||
/**
|
||
* edit calendar page
|
||
*/
|
||
public function edit(Calendar $calendar)
|
||
{
|
||
$this->authorize('update', $calendar);
|
||
|
||
$calendar->load([
|
||
'meta',
|
||
'instances' => fn ($q) =>
|
||
$q->where('principaluri', 'principals/'.auth()->id()),
|
||
]);
|
||
|
||
$instance = $calendar->instances->first(); // may be null but shouldn’t
|
||
|
||
return view('calendars.edit', compact('calendar', 'instance'));
|
||
}
|
||
|
||
/**
|
||
* update sabre + meta records
|
||
*/
|
||
public function update(Request $request, Calendar $calendar)
|
||
{
|
||
$this->authorize('update', $calendar);
|
||
|
||
$data = $request->validate([
|
||
'name' => 'required|string|max:100',
|
||
'description' => 'nullable|string|max:255',
|
||
'timezone' => 'required|string',
|
||
'color' => 'nullable|regex:/^#[0-9A-Fa-f]{6}$/',
|
||
]);
|
||
|
||
// update the instance row
|
||
$calendar->instances()
|
||
->where('principaluri', 'principals/'.auth()->id())
|
||
->update([
|
||
'displayname' => $data['name'],
|
||
'description' => $data['description'] ?? '',
|
||
'calendarcolor' => $data['color'] ?? null,
|
||
'timezone' => $data['timezone'],
|
||
]);
|
||
|
||
// bump synctoken on master calendar row
|
||
$calendar->increment('synctoken');
|
||
|
||
// update calendar meta (our table)
|
||
$calendar->meta()->updateOrCreate([], [
|
||
'color' => $data['color'] ?? null]
|
||
);
|
||
|
||
return redirect()
|
||
->route('calendars.show', $calendar)
|
||
->with('toast', __('Calendar saved successfully!'));
|
||
}
|
||
|
||
/**
|
||
* delete calendar @todo
|
||
*/
|
||
public function destroy(Calendar $calendar)
|
||
{
|
||
$this->authorize('delete', $calendar);
|
||
$calendar->delete(); // cascades to meta via FK
|
||
return redirect()->route('calendars.index');
|
||
}
|
||
}
|