256 lines
8.7 KiB
PHP
256 lines
8.7 KiB
PHP
<?php
|
|
|
|
namespace app\controller\Api;
|
|
|
|
use app\service\ArchiveRepository;
|
|
use support\Response;
|
|
use Throwable;
|
|
|
|
class EvidenceController
|
|
{
|
|
public function archive(string $archiveUid): Response
|
|
{
|
|
try {
|
|
$archive = (new ArchiveRepository())->findArchive($archiveUid);
|
|
} catch (Throwable $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 500,
|
|
'message' => 'Archive lookup failed.',
|
|
'errors' => ['archive' => $exception->getMessage()],
|
|
], 500);
|
|
}
|
|
|
|
if ($archive === null) {
|
|
return $this->jsonResponse([
|
|
'code' => 404,
|
|
'message' => 'Archive not found.',
|
|
'errors' => ['archive_uid' => $archiveUid],
|
|
], 404);
|
|
}
|
|
|
|
$archive['chunk_count'] = is_array($archive['chunks'] ?? null) ? count($archive['chunks']) : 0;
|
|
|
|
return $this->jsonResponse([
|
|
'code' => 0,
|
|
'message' => 'Archive loaded.',
|
|
'data' => $archive,
|
|
], 200);
|
|
}
|
|
|
|
public function chunk(string $chunkUid): Response
|
|
{
|
|
try {
|
|
$chunk = (new ArchiveRepository())->findChunk($chunkUid);
|
|
} catch (Throwable $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 500,
|
|
'message' => 'Chunk lookup failed.',
|
|
'errors' => ['chunk' => $exception->getMessage()],
|
|
], 500);
|
|
}
|
|
|
|
if ($chunk === null) {
|
|
return $this->jsonResponse([
|
|
'code' => 404,
|
|
'message' => 'Chunk not found.',
|
|
'errors' => ['chunk_uid' => $chunkUid],
|
|
], 404);
|
|
}
|
|
|
|
return $this->jsonResponse([
|
|
'code' => 0,
|
|
'message' => 'Chunk loaded.',
|
|
'data' => $chunk,
|
|
], 200);
|
|
}
|
|
|
|
public function archiveChunks(string $archiveUid): Response
|
|
{
|
|
try {
|
|
$repository = new ArchiveRepository();
|
|
$archive = $repository->findArchive($archiveUid);
|
|
$chunks = $archive === null ? [] : $repository->findArchiveChunks($archiveUid);
|
|
} catch (Throwable $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 500,
|
|
'message' => 'Archive chunks lookup failed.',
|
|
'errors' => ['archive_chunks' => $exception->getMessage()],
|
|
], 500);
|
|
}
|
|
|
|
if ($archive === null) {
|
|
return $this->jsonResponse([
|
|
'code' => 404,
|
|
'message' => 'Archive not found.',
|
|
'errors' => ['archive_uid' => $archiveUid],
|
|
], 404);
|
|
}
|
|
|
|
return $this->jsonResponse([
|
|
'code' => 0,
|
|
'message' => 'Archive chunks loaded.',
|
|
'data' => [
|
|
'archive_uid' => $archive['archive_uid'],
|
|
'title' => $archive['title'],
|
|
'summary' => $archive['summary'],
|
|
'source' => $archive['source'],
|
|
'author' => $archive['author'],
|
|
'year' => $archive['year'],
|
|
'series' => $archive['series'],
|
|
'tags' => $archive['tags'],
|
|
'chunk_count' => count($chunks),
|
|
'chunks' => $chunks,
|
|
],
|
|
], 200);
|
|
}
|
|
|
|
public function evidence(string $chunkUid): Response
|
|
{
|
|
try {
|
|
$chunk = (new ArchiveRepository())->findChunk($chunkUid);
|
|
} catch (Throwable $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 500,
|
|
'message' => 'Evidence lookup failed.',
|
|
'errors' => ['evidence' => $exception->getMessage()],
|
|
], 500);
|
|
}
|
|
|
|
if ($chunk === null) {
|
|
return $this->jsonResponse([
|
|
'code' => 404,
|
|
'message' => 'Evidence not found.',
|
|
'errors' => ['chunk_uid' => $chunkUid],
|
|
], 404);
|
|
}
|
|
|
|
$archive = $chunk['archive'];
|
|
$pages = $chunk['pages'];
|
|
$pageLabel = $this->pageLabel($pages);
|
|
|
|
return $this->jsonResponse([
|
|
'code' => 0,
|
|
'message' => 'Evidence loaded.',
|
|
'data' => [
|
|
'chunk_uid' => $chunk['chunk_uid'],
|
|
'archive_uid' => $chunk['archive_uid'],
|
|
'title' => $archive['title'] ?? null,
|
|
'source' => $archive['source'] ?? null,
|
|
'author' => $archive['author'] ?? null,
|
|
'year' => $archive['year'] ?? null,
|
|
'series' => $archive['series'] ?? null,
|
|
'tags' => $archive['tags'] ?? [],
|
|
'page_start' => $chunk['page_start'],
|
|
'page_end' => $chunk['page_end'],
|
|
'pages' => $pages,
|
|
'page_label' => $pageLabel,
|
|
'citation' => $this->citation($archive, $pageLabel),
|
|
'quote' => $chunk['text'],
|
|
'chunk' => [
|
|
'chunk_index' => $chunk['chunk_index'],
|
|
'length' => $chunk['length'],
|
|
'embedding_model' => $chunk['embedding_model'],
|
|
'embedding_status' => $chunk['embedding_status'],
|
|
'search_index_status' => $chunk['search_index_status'],
|
|
],
|
|
],
|
|
], 200);
|
|
}
|
|
|
|
public function archiveEvidence(string $archiveUid): Response
|
|
{
|
|
try {
|
|
$repository = new ArchiveRepository();
|
|
$archive = $repository->findArchive($archiveUid);
|
|
$chunks = $archive === null ? [] : $repository->findArchiveChunks($archiveUid);
|
|
} catch (Throwable $exception) {
|
|
return $this->jsonResponse([
|
|
'code' => 500,
|
|
'message' => 'Archive evidence lookup failed.',
|
|
'errors' => ['archive_evidence' => $exception->getMessage()],
|
|
], 500);
|
|
}
|
|
|
|
if ($archive === null) {
|
|
return $this->jsonResponse([
|
|
'code' => 404,
|
|
'message' => 'Archive not found.',
|
|
'errors' => ['archive_uid' => $archiveUid],
|
|
], 404);
|
|
}
|
|
|
|
$evidence = array_map(function (array $chunk): array {
|
|
$archive = $chunk['archive'];
|
|
$pages = $chunk['pages'];
|
|
$pageLabel = $this->pageLabel($pages);
|
|
|
|
return [
|
|
'chunk_uid' => $chunk['chunk_uid'],
|
|
'chunk_index' => $chunk['chunk_index'],
|
|
'page_start' => $chunk['page_start'],
|
|
'page_end' => $chunk['page_end'],
|
|
'pages' => $pages,
|
|
'page_label' => $pageLabel,
|
|
'citation' => $this->citation($archive, $pageLabel),
|
|
'quote' => $chunk['text'],
|
|
'length' => $chunk['length'],
|
|
'embedding_model' => $chunk['embedding_model'],
|
|
'embedding_status' => $chunk['embedding_status'],
|
|
'search_index_status' => $chunk['search_index_status'],
|
|
];
|
|
}, $chunks);
|
|
|
|
return $this->jsonResponse([
|
|
'code' => 0,
|
|
'message' => 'Archive evidence loaded.',
|
|
'data' => [
|
|
'archive_uid' => $archive['archive_uid'],
|
|
'title' => $archive['title'],
|
|
'summary' => $archive['summary'],
|
|
'source' => $archive['source'],
|
|
'author' => $archive['author'],
|
|
'year' => $archive['year'],
|
|
'series' => $archive['series'],
|
|
'tags' => $archive['tags'],
|
|
'chunk_count' => count($evidence),
|
|
'evidence' => $evidence,
|
|
],
|
|
], 200);
|
|
}
|
|
|
|
private function citation(array $archive, string $pageLabel): string
|
|
{
|
|
$parts = array_values(array_filter([
|
|
$archive['title'] ?? null,
|
|
$archive['author'] ?? null,
|
|
isset($archive['year']) ? (string) $archive['year'] : null,
|
|
$pageLabel === '' ? null : $pageLabel,
|
|
$archive['source'] ?? null,
|
|
], static fn ($value): bool => $value !== null && trim((string) $value) !== ''));
|
|
|
|
return implode(' | ', $parts);
|
|
}
|
|
|
|
private function pageLabel(array $pages): string
|
|
{
|
|
if ($pages === []) {
|
|
return '';
|
|
}
|
|
|
|
if (count($pages) === 1) {
|
|
return 'p. ' . (string) $pages[0];
|
|
}
|
|
|
|
return 'pp. ' . (string) $pages[0] . '-' . (string) $pages[count($pages) - 1];
|
|
}
|
|
|
|
private function jsonResponse(array $data, int $status): Response
|
|
{
|
|
return response(
|
|
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR),
|
|
$status,
|
|
['Content-Type' => 'application/json']
|
|
);
|
|
}
|
|
}
|