source->name === self::SOURCE; } /** * @param array{title:string, due_at:string, subtitle?:?string, fire_at?:?string, after_due?:?string, done_label?:?string, deep_link?:?string} $fields */ public function create(User $user, array $fields): Event { return $this->upsert($user, 'manual:'.Str::ulid(), $fields); } private function upsert(User $user, string $sourceRef, array $fields): Event { [$result] = $this->upserter->upsert($this->source(), [[ 'user' => $user->login, 'source_ref' => $sourceRef, 'topic' => '', 'due_at' => $fields['due_at'], 'fire_at' => $fields['fire_at'] ?? self::defaultFireAt($fields['due_at']), 'after_due' => $fields['after_due'] ?? 'keep', 'payload' => array_filter([ 'title' => $fields['title'], 'subtitle' => $fields['subtitle'] ?? null, 'done_label' => $fields['done_label'] ?? 'Сделано', 'deep_link' => $fields['deep_link'] ?? null, ], fn ($v) => $v !== null && $v !== ''), ]]); return Event::with('source')->findOrFail($result['id']); } private function source(): Source { return Source::firstOrCreate(['name' => self::SOURCE], ['token_hash' => hash('sha256', Str::random(64))]); } /** День срока минус DEFAULT_LEAD_DAYS; из due_at берётся только дата. */ private static function defaultFireAt(string $dueAt): string { return CarbonImmutable::createFromFormat('Y-m-d', substr($dueAt, 0, 10))->subDays(self::DEFAULT_LEAD_DAYS)->format('Y-m-d'); } }