Skip to content

Commit 037ebca

Browse files
committed
Sitemap generator and route handling and remove // from opengraph image
1 parent ce17b13 commit 037ebca

11 files changed

Lines changed: 237 additions & 3 deletions

bin/sitemap

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
declare(strict_types=1);
5+
6+
use Light\App\Service\SitemapGenerator;
7+
8+
chdir(__DIR__ . '/../');
9+
10+
require 'vendor/autoload.php';
11+
12+
$container = require 'config/container.php';
13+
$sitemapGenerator = $container->get(SitemapGenerator::class);
14+
15+
$count = $sitemapGenerator->write();
16+
17+
printf(
18+
"Done. %d url%s written to %s%s",
19+
$count,
20+
$count === 1 ? '' : 's',
21+
$sitemapGenerator->getSitemapFile(),
22+
PHP_EOL
23+
);

config/autoload/local.php.dist

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ return [
5959
'feed' => [
6060
'path' => realpath(__DIR__ . '/../../public/feed.xml'),
6161
],
62+
'sitemap' => [
63+
'path' => realpath(__DIR__ . '/../../public/sitemap.xml'),
64+
],
6265
'routes' => [
6366
'page' => [
6467
'contact' => 'contact',

public/sitemap.xml

Whitespace-only changes.

src/App/src/ConfigProvider.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616
use Light\App\Factory\GetFeedViewHandlerFactory;
1717
use Light\App\Factory\GetIndexViewHandlerFactory;
1818
use Light\App\Factory\GetMarkdownArticleHandlerFactory;
19+
use Light\App\Factory\GetSitemapViewHandlerFactory;
20+
use Light\App\Factory\SitemapGeneratorFactory;
1921
use Light\App\Handler\GetFeedViewHandler;
2022
use Light\App\Handler\GetIndexViewHandler;
2123
use Light\App\Handler\GetMarkdownArticleHandler;
24+
use Light\App\Handler\GetSitemapViewHandler;
2225
use Light\App\Resolver\EntityListenerResolver;
2326
use Light\App\Service\FeedGenerator;
27+
use Light\App\Service\SitemapGenerator;
2428
use Mezzio\Application;
2529
use Roave\PsrContainerDoctrine\EntityManagerFactory;
2630
use Symfony\Component\Cache\Adapter\AdapterInterface;
@@ -121,7 +125,9 @@ public function getDependencies(): array
121125
GetIndexViewHandler::class => GetIndexViewHandlerFactory::class,
122126
GetFeedViewHandler::class => GetFeedViewHandlerFactory::class,
123127
GetMarkdownArticleHandler::class => GetMarkdownArticleHandlerFactory::class,
128+
GetSitemapViewHandler::class => GetSitemapViewHandlerFactory::class,
124129
FeedGenerator::class => FeedGeneratorFactory::class,
130+
SitemapGenerator::class => SitemapGeneratorFactory::class,
125131
],
126132
'aliases' => [
127133
EntityManager::class => 'doctrine.entity_manager.orm_default',

src/App/src/Factory/FeedGeneratorFactory.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use Psr\Container\ContainerInterface;
1010

1111
use function assert;
12-
use function rtrim;
1312

1413
class FeedGeneratorFactory
1514
{
@@ -23,7 +22,7 @@ public function __invoke(ContainerInterface $container): FeedGenerator
2322
return new FeedGenerator(
2423
$postRepository,
2524
$config['feed']['path'],
26-
rtrim($config['application']['baseUrl'] ?? '', '/') . '/',
25+
$config['application']['baseUrl'] ?? '',
2726
$config['application']['meta']['title'] ?? '',
2827
$config['application']['meta']['description'] ?? '',
2928
$config['application']['meta']['image'] ?? '',
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\App\Factory;
6+
7+
use Light\App\Handler\GetSitemapViewHandler;
8+
use Light\App\Service\SitemapGenerator;
9+
use Light\Blog\Repository\CategoryRepository;
10+
use Mezzio\Template\TemplateRendererInterface;
11+
use Psr\Container\ContainerInterface;
12+
13+
use function assert;
14+
15+
class GetSitemapViewHandlerFactory
16+
{
17+
/**
18+
* @param class-string $requestedName
19+
*/
20+
public function __invoke(ContainerInterface $container, string $requestedName): GetSitemapViewHandler
21+
{
22+
$template = $container->get(TemplateRendererInterface::class);
23+
assert($template instanceof TemplateRendererInterface);
24+
25+
$categoryRepository = $container->get(CategoryRepository::class);
26+
assert($categoryRepository instanceof CategoryRepository);
27+
28+
$sitemapGenerator = $container->get(SitemapGenerator::class);
29+
assert($sitemapGenerator instanceof SitemapGenerator);
30+
31+
return new GetSitemapViewHandler($template, $categoryRepository, $sitemapGenerator);
32+
}
33+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\App\Factory;
6+
7+
use Light\App\Service\SitemapGenerator;
8+
use Light\Blog\Repository\PostRepository;
9+
use Psr\Container\ContainerInterface;
10+
11+
use function assert;
12+
13+
class SitemapGeneratorFactory
14+
{
15+
public function __invoke(ContainerInterface $container): SitemapGenerator
16+
{
17+
$postRepository = $container->get(PostRepository::class);
18+
assert($postRepository instanceof PostRepository);
19+
20+
$config = $container->get('config');
21+
22+
return new SitemapGenerator(
23+
$postRepository,
24+
$config['sitemap']['path'],
25+
$config['application']['baseUrl'] ?? '',
26+
);
27+
}
28+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\App\Handler;
6+
7+
use Fig\Http\Message\StatusCodeInterface;
8+
use Laminas\Diactoros\Response\HtmlResponse;
9+
use Laminas\Diactoros\Response\XmlResponse;
10+
use Light\App\Service\SitemapGenerator;
11+
use Light\Blog\Entity\Category;
12+
use Light\Blog\Repository\CategoryRepository;
13+
use Mezzio\Template\TemplateRendererInterface;
14+
use Psr\Http\Message\ResponseInterface;
15+
use Psr\Http\Message\ServerRequestInterface;
16+
use Psr\Http\Server\RequestHandlerInterface;
17+
use Throwable;
18+
19+
use function file_get_contents;
20+
use function filesize;
21+
use function is_file;
22+
23+
class GetSitemapViewHandler implements RequestHandlerInterface
24+
{
25+
public function __construct(
26+
private readonly TemplateRendererInterface $template,
27+
private readonly CategoryRepository $categoryRepository,
28+
private readonly SitemapGenerator $sitemapGenerator,
29+
) {
30+
}
31+
32+
public function handle(ServerRequestInterface $request): ResponseInterface
33+
{
34+
$sitemapFile = $this->sitemapGenerator->getSitemapFile();
35+
36+
if (! is_file($sitemapFile) || filesize($sitemapFile) === 0) {
37+
try {
38+
$this->sitemapGenerator->write();
39+
} catch (Throwable) {
40+
}
41+
}
42+
43+
if (! is_file($sitemapFile) || filesize($sitemapFile) === 0) {
44+
return $this->notFound($this->categoryRepository->getCategories());
45+
}
46+
47+
return new XmlResponse(
48+
(string) file_get_contents($sitemapFile),
49+
StatusCodeInterface::STATUS_OK,
50+
['Content-Type' => SitemapGenerator::CONTENT_TYPE]
51+
);
52+
}
53+
54+
/**
55+
* @param Category[] $categories
56+
*/
57+
private function notFound(array $categories): HtmlResponse
58+
{
59+
return new HtmlResponse(
60+
$this->template->render('error::404', [
61+
'categories' => $categories,
62+
]),
63+
StatusCodeInterface::STATUS_NOT_FOUND
64+
);
65+
}
66+
}

src/App/src/RoutesDelegator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Light\App\Handler\GetFeedViewHandler;
99
use Light\App\Handler\GetIndexViewHandler;
1010
use Light\App\Handler\GetMarkdownArticleHandler;
11+
use Light\App\Handler\GetSitemapViewHandler;
1112
use Mezzio\Application;
1213
use Psr\Container\ContainerInterface;
1314

@@ -21,6 +22,7 @@ public function __invoke(ContainerInterface $container, string $serviceName, cal
2122
assert($app instanceof Application);
2223
$app->get('/', [GetIndexViewHandler::class], 'app::index');
2324
$app->get('/feed/', [GetFeedViewHandler::class], 'app::feed');
25+
$app->get('/sitemap/', [GetSitemapViewHandler::class], 'app::sitemap');
2426
$app->get('/{categorySlug}/{slug}.md', [GetMarkdownArticleHandler::class], 'app::markdown-article');
2527

2628
$app->get('/{first}', function ($request) {

src/App/src/Service/FeedGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function write(): int
5555
$this->appendText($dom, $channel, 'lastBuildDate', (new DateTimeImmutable())->format(DateTimeInterface::RSS));
5656

5757
foreach ($posts as $post) {
58-
$link = $this->baseUrl . $post->getCategory()->getSlug() . '/' . $post->getSlug() . '/';
58+
$link = $this->baseUrl . '/' . $post->getCategory()->getSlug() . '/' . $post->getSlug() . '/';
5959

6060
$item = $dom->createElement('item');
6161
$channel->appendChild($item);

0 commit comments

Comments
 (0)