Files
hado/core/app/Ingest/ManualEvents.php

69 lines
2.5 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\Ingest;
use App\Models\Event;
use App\Models\Source;
use App\Models\User;
use Carbon\CarbonImmutable;
use Illuminate\Support\Str;
/**
* События, которые пользователь заводит сам — кнопкой в инбоксе или через агента.
* Источник один: `manual`. Только его события пользователь правит и снимает;
* чужие источники правят своё сами.
*/
final class ManualEvents
{
public const SOURCE = 'manual';
/** Старт подготовки по умолчанию: за столько дней до срока. */
public const DEFAULT_LEAD_DAYS = 30;
public function __construct(private readonly EventUpserter $upserter) {}
public static function owns(Event $event): bool
{
return $event->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');
}
}