attributes->get('source'); return response()->json(['events' => $this->upserter->upsert($source, $request->items())]); } public function show(Request $request): JsonResponse { $event = $this->lookup($request); return response()->json(self::present($event)); } public function destroy(Request $request): Response { $event = $this->lookup($request); $event->update(['state' => EventState::Withdrawn]); return response()->noContent(); } private function lookup(Request $request): Event { $request->validate(['source_ref' => ['required', 'string'], 'topic' => ['sometimes', 'nullable', 'string']]); /** @var Source $source */ $source = $request->attributes->get('source'); $event = $this->upserter->find($source, $request->query('source_ref'), (string) $request->query('topic', '')); abort_if($event === null, 404, 'Событие не найдено'); return $event; } /** @return array */ public static function present(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(), ]; } private 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); } }