*/ public static function forClient(Event $event): array { return [ 'id' => $event->id, 'source_ref' => $event->source_ref, 'topic' => $event->topic, 'state' => $event->state->value, 'due_at' => self::dueAt($event), 'fire_at' => $event->fire_on->format('Y-m-d'), 'after_due' => $event->after_due->value, 'payload' => $event->payload, 'done_at' => $event->done_at?->toIso8601String(), ]; } /** * Пользователю (и агенту) поверх клиентского: чей источник и можно ли править. * `editable` — явный флаг, а не «сравни source со строкой». * * @return array */ public static function forUser(Event $event): array { return self::forClient($event) + [ 'source' => $event->source->name, 'editable' => ManualEvents::owns($event), ]; } /** Подпись закрытого события в архиве. */ public static function closedAs(Event $event): string { return $event->state === EventState::Expired ? 'Истекло' : ($event->payload['done_label'] ?? 'Сделано'); } public static function dueAt(Event $event): string { if ($event->due_mode === DueMode::Fixed) { return $event->due_instant->toIso8601String(); } $date = $event->due_date->format('Y-m-d'); return $event->due_time === DueResolver::WHOLE_DAY ? $date : $date.'T'.substr($event->due_time, 0, 5); } }