Repository navigation
Expand file tree
/
Copy pathGetPostResourceHandler.php
More file actions
108 lines (96 loc) · 4 KB
/
Copy pathGetPostResourceHandler.php
File metadata and controls
108 lines (96 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
declare(strict_types=1);
namespace Light\Blog\Handler;
use Fig\Http\Message\StatusCodeInterface;
use Laminas\Diactoros\Response\HtmlResponse;
use Laminas\Diactoros\Response\TextResponse;
use Light\App\Service\ArticleBodyCleaner;
use Light\App\Service\FaqExtractor;
use Light\App\Service\FrontMatter;
use Light\Blog\Enum\PostStatusEnum;
use Light\Blog\Repository\CategoryRepository;
use Light\Blog\Repository\PostRepository;
use Light\Blog\Service\BlogServiceInterface;
use Mezzio\Template\TemplateRendererInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Throwable;
use function file_get_contents;
use function str_contains;
class GetPostResourceHandler implements RequestHandlerInterface
{
public function __construct(
private readonly TemplateRendererInterface $template,
private readonly PostRepository $articleRepository,
private readonly CategoryRepository $categoryRepository,
private readonly BlogServiceInterface $blogService,
) {
}
public function handle(ServerRequestInterface $request): ResponseInterface
{
$slug = (string) $request->getAttribute('slug');
$categorySlug = (string) $request->getAttribute('categorySlug');
if (str_contains($request->getHeaderLine('Accept'), 'text/markdown')) {
$markdownFile = $this->blogService->resolveMarkdownFilePath($categorySlug, $slug);
if ($markdownFile !== null) {
return new TextResponse(
(string) file_get_contents($markdownFile),
StatusCodeInterface::STATUS_OK,
['Content-Type' => 'text/markdown; charset=utf-8'],
);
}
}
$categories = $this->categoryRepository->getCategories();
$article = $this->articleRepository->getArticleResource($slug, $categorySlug);
if ($article === null) {
return $this->blogService->notFound($categories);
}
if ($article->getStatus() === PostStatusEnum::Archived) {
return $this->blogService->gone($categories);
}
if ($article->getStatus() !== PostStatusEnum::Published) {
return $this->blogService->notFound($categories);
}
$adjacent = $this->articleRepository->getAdjacentPosts($article);
if ($article->isTwig()) {
try {
$html = $this->template->render(
"page::blog-resource/{$categorySlug}/{$slug}",
[
'article' => $article,
'categories' => $categories,
'previousPost' => $adjacent['previous'],
'nextPost' => $adjacent['next'],
'faq' => [],
]
);
return new HtmlResponse($html);
} catch (Throwable $e) {
return $this->blogService->notFound($categories);
}
}
$markdownFile = $this->blogService->resolveMarkdownFilePath($categorySlug, $slug);
if ($markdownFile === null) {
return $this->blogService->notFound($categories);
}
$parsed = FrontMatter::parse((string) file_get_contents($markdownFile));
$faq = FaqExtractor::extract(ArticleBodyCleaner::clean($parsed['body']));
try {
$html = $this->template->render(
'page::markdown-article',
[
'article' => $article,
'categories' => $categories,
'previousPost' => $adjacent['previous'],
'nextPost' => $adjacent['next'],
'content' => $faq['body'],
'faq' => $faq['faq'],
]
);
return new HtmlResponse($html);
} catch (Throwable $e) {
return $this->blogService->notFound($categories);
}
}
}