kithkin/app/Http/Controllers/EventController.php

165 lines
5.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use App\Models\Calendar;
use App\Models\Event;
use App\Models\EventMeta;
class EventController extends Controller
{
public function create(Calendar $calendar)
{
$this->authorize('update', $calendar);
return view('events.form', ['calendar' => $calendar, 'event' => new Event]);
}
/**
* insert VEVENT into Sabres calendarobjects + meta row
*/
public function store(Request $req, Calendar $calendar)
{
$this->authorize('update', $calendar);
$data = $req->validate([
'title' => 'required|string|max:200',
'start_at' => 'required|date',
'end_at' => 'required|date|after:start_at',
'description' => 'nullable|string',
'location' => 'nullable|string',
'all_day' => 'sometimes|boolean',
'category' => 'nullable|string|max:50',
]);
// prepare payload
$uid = Str::uuid() . '@' . parse_url(config('app.url'), PHP_URL_HOST);
$start = new Carbon($data['start_at'], $calendar->timezone);
$end = new Carbon($data['end_at'], $calendar->timezone);
// prepare strings
$description = $data['description'] ?? '';
$location = $data['location'] ?? '';
$description = str_replace("\n", '\\n', $description);
$location = str_replace("\n", '\\n', $location);
/* build minimal iCalendar payload */
$ical = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Kithkin//Laravel CalDAV//EN
BEGIN:VEVENT
UID:$uid
DTSTAMP:{$start->utc()->format('Ymd\\THis\\Z')}
DTSTART:{$start->format('Ymd\\THis')}
DTEND:{$end->format('Ymd\\THis')}
SUMMARY:{$data['title']}
DESCRIPTION:$description
LOCATION:$location
END:VEVENT
END:VCALENDAR
ICS;
$event = Event::create([
'calendarid' => $calendar->id,
'uri' => Str::uuid() . '.ics',
'lastmodified' => time(),
'etag' => md5($ical),
'size' => strlen($ical),
'componenttype' => 'VEVENT',
'uid' => $uid,
'calendardata' => $ical,
]);
$event->meta()->create([
'title' => $data['title'],
'description' => $data['description'] ?? null,
'location' => $data['location'] ?? null,
'all_day' => $data['all_day'] ?? false,
'category' => $data['category'] ?? null,
'start_at' => $start,
'end_at' => $end,
]);
return redirect()->route('calendars.show', $calendar);
}
public function edit(Calendar $calendar, Event $event)
{
$this->authorize('update', $calendar);
return view('events.form', compact('calendar', 'event'));
}
/**
* update vevent + meta
*/
public function update(Request $req, Calendar $calendar, Event $event)
{
$this->authorize('update', $calendar);
$data = $req->validate([
'title' => 'required|string|max:200',
'start_at' => 'required|date',
'end_at' => 'required|date|after:start_at',
'description' => 'nullable|string',
'location' => 'nullable|string',
'category' => 'nullable|string|max:50',
]);
// rebuild the icalendar payload
$tz = $calendar->timezone;
$start = new \Carbon\Carbon($data['start_at'], $tz);
$end = new \Carbon\Carbon($data['end_at'], $tz);
// prepare strings
$description = $data['description'] ?? '';
$location = $data['location'] ?? '';
$description = str_replace("\n", '\\n', $description);
$location = str_replace("\n", '\\n', $location);
// note: keep the UID stable (CalDAV relies on it!)
$uid = $event->uid;
$ical = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Kithkin//Laravel CalDAV//EN
BEGIN:VEVENT
UID:$uid
DTSTAMP:{$start->utc()->format('Ymd\\THis\\Z')}
DTSTART;TZID={$tz}:{$start->format('Ymd\\THis')}
DTEND;TZID={$tz}:{$end->format('Ymd\\THis')}
SUMMARY:{$data['title']}
DESCRIPTION:$description
LOCATION:$location
END:VEVENT
END:VCALENDAR
ICS;
// persist changes
$event->update([
'calendardata' => $ical,
'etag' => md5($ical),
'lastmodified' => time(),
]);
$event->meta()->updateOrCreate([], [
'title' => $data['title'],
'description' => $data['description'] ?? null,
'location' => $data['location'] ?? null,
'all_day' => $data['all_day'] ?? false,
'category' => $data['category'] ?? null,
'start_at' => $start,
'end_at' => $end,
]);
return redirect()->route('calendars.show', $calendar);
}
}