kithkin/database/seeders/DatabaseSeeder.php

271 lines
8.6 KiB
PHP

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use App\Models\User;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
/**
*
* admin users
*/
// credentials from .env (with sensible fall-backs)
$email = env('ADMIN_EMAIL', 'admin@example.com');
$password = env('ADMIN_PASSWORD', 'changeme');
$firstname = env('ADMIN_FIRSTNAME', 'Admin');
$lastname = env('ADMIN_LASTNAME', 'Account');
$timezone = env('APP_TIMEZONE', 'UTC');
// create or update the admin user
$user = User::updateOrCreate(
['email' => $email],
[
'firstname' => $firstname,
'lastname' => $lastname,
'timezone' => $timezone,
'password' => Hash::make($password),
]
);
// fill the sabre-friendly columns
$user->update([
'uri' => 'principals/'.$user->email,
'displayname' => $firstname.' '.$lastname,
]);
/**
*
* calendar and meta
*/
// sample caldav data
$calId = DB::table('calendars')->insertGetId([
'synctoken' => 1,
'components' => 'VEVENT',
]);
$instanceId = DB::table('calendarinstances')->insertGetId([
'calendarid' => $calId,
'principaluri' => $user->uri, // uses new column
'uri' => Str::uuid(),
'displayname' => 'Sample Calendar',
'description' => 'Seeded calendar',
'calendarorder' => 0,
'calendarcolor' => '#0038ff',
'timezone' => $timezone,
]);
DB::table('calendar_meta')->updateOrInsert(
['calendar_id' => $calId], // @todo should this be calendar id or instance id?
['color' => '#0038ff']
);
/**
*
* create the locations connected to each event
**/
// locations
$locationSeeds = [
'Home' => [ // free-text, no geo
'display' => 'Home',
'raw' => null,
],
'Living Room' => [
'display' => 'Living Room',
'raw' => null,
],
'McCahill Park' => [
'display' => 'McCahill Park',
'raw' => '625 Hemlock Hollow Rd, Pittsburgh, PA 15238',
],
'Meadow Park' => [
'display' => 'Meadow Park',
'raw' => '2 Meadow Park Lane, Pittsburgh, PA 15215',
],
'AHN Pediatrics' => [
'display' => 'AHN Pediatrics',
'raw' => '3394 Saxonburg Blvd Suite 600, Glenshaw, PA 15116',
],
'The Discovery School' => [
'display' => 'The Discovery School',
'raw' => '4225 Middle Rd, Allison Park, PA 15101',
],
'Fairview Elementary School' => [
'display' => 'Fairview Elementary School',
'raw' => '738 Dorseyville Rd, Pittsburgh, PA 15238',
],
];
// create the locations first
$locationIdMap = [];
foreach ($locationSeeds as $key => $data) {
$locId = DB::table('locations')->updateOrInsert(
['display_name' => $data['display']], // uniqueness key
[
'raw_address' => $data['raw'],
'created_at' => now(),
'updated_at' => now(),
]
);
// updateOrInsert returns boolean; fetch id explicitly
$locId = DB::table('locations')->where('display_name', $data['display'])->value('id');
$locationIdMap[$key] = $locId;
}
/**
*
* cevent creation helper function
**/
$insertEvent = function (Carbon $start,
string $summary,
string $locationKey) use ($calId, $locationIdMap)
{
// set base vars
$uid = Str::uuid().'@kithkin.lan';
$end = $start->copy()->addHour();
// create UTC copies for the ICS fields
$dtstamp = $start->copy()->utc()->format('Ymd\\THis\\Z');
$dtstart = $start->copy()->utc()->format('Ymd\\THis\\Z');
$dtend = $end->copy()->utc()->format('Ymd\\THis\\Z');
$locationDisplay = $locationKey;
$locationRaw = $locationSeeds[$locationKey]['raw'] ?? null;
$icalLocation = $locationRaw ?? $locationDisplay;
$ical = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Kithkin//Laravel CalDAV//EN
BEGIN:VEVENT
UID:$uid
DTSTAMP:$dtstamp
DTSTART:$dtstart
DTEND:$dtend
SUMMARY:$summary
DESCRIPTION:Automatically seeded event
LOCATION:Home Office
END:VEVENT
END:VCALENDAR
ICS;
$eventId = DB::table('calendarobjects')->insertGetId([
'calendarid' => $calId,
'uri' => Str::uuid().'.ics',
'lastmodified' => time(),
'etag' => md5($ical),
'size' => strlen($ical),
'componenttype' => 'VEVENT',
'uid' => $uid,
'calendardata' => $ical,
]);
DB::table('event_meta')->updateOrInsert(
['event_id' => $eventId],
[
'title' => $summary,
'description' => 'Automatically seeded event',
'location' => $locationRaw ? null : $locationDisplay,
'location_id' => $locationIdMap[$locationKey] ?? null,
'all_day' => false,
'category' => 'Demo',
'start_at' => $start->copy()->utc(),
'end_at' => $end->copy()->utc(),
'created_at' => now(),
'updated_at' => now(),
]
);
};
/**
*
* create events
*/
$now = Carbon::now()->setSeconds(0);
// 3 events today
$insertEvent($now->copy(), 'Playground with James', 'McCaHill Park');
$insertEvent($now->copy()->addHours(2), 'Lunch with Daniel', 'Home');
$insertEvent($now->copy()->addHours(4), 'Baseball practice', 'Meadow Park');
// 1 event 3 days ago
$past = $now->copy()->subDays(3)->setTime(10, 0);
$insertEvent($past, 'Kids doctors appointments', 'AHN Pediatrics');
// 1 event 2 days ahead
$future2 = $now->copy()->addDays(2)->setTime(14, 0);
$insertEvent($future2, 'Teacher conference (Nuthatches)', 'The Discovery School');
// 2 events 5 days ahead
$future5a = $now->copy()->addDays(5)->setTime(9, 0);
$future5b = $future5a->copy()->addHours(2);
$insertEvent($future5a, 'Teacher conference (3rd grade)', 'Fairview Elementary');
$insertEvent($future5b, 'Family game night', 'Living Room');
/**
*
* address books
*
*/
// create cards
$bookId = DB::table('addressbooks')->insertGetId([
'principaluri' => $user->uri,
'uri' => 'default',
'displayname' => 'Default Address Book',
]);
$vcard = <<<VCF
BEGIN:VCARD
VERSION:3.0
FN:Seeded Contact
EMAIL:seeded@example.com
TEL:+1-555-123-4567
UID:seeded-contact-001
END:VCARD
VCF;
DB::table('addressbook_meta')->insert([
'addressbook_id' => $bookId,
'color' => '#ff40ff',
'is_default' => true,
'settings' => null,
'created_at' => now(),
'updated_at' => now(),
]);
$cardId = DB::table('cards')->insertGetId([
'addressbookid' => $bookId,
'uri' => Str::uuid().'.vcf',
'lastmodified' => now()->timestamp,
'etag' => md5($vcard),
'size' => strlen($vcard),
'carddata' => $vcard,
]);
DB::table('contact_meta')->insert([
'card_id' => $cardId,
'avatar_url' => null,
'tags' => 'demo,seed',
'notes' => 'Seeded contact from DatabaseSeeder.',
'created_at' => now(),
'updated_at' => now(),
]);
}
}