Skip to content

Commit 29a47a0

Browse files
committed
index.php: Move routes to a class
Simplifies the entry point, similarly to what Nette does.
1 parent 6ef2fc4 commit 29a47a0

File tree

2 files changed

+190
-159
lines changed

2 files changed

+190
-159
lines changed

index.php

Lines changed: 5 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -2,167 +2,13 @@
22

33
declare(strict_types=1);
44

5+
// SPDX-License-Identifier: GPL-3.0-or-later
6+
// SPDX-FileCopyrightText: 2025 Jan Tojnar <jtojnar@gmail.com>
7+
58
use Psr\Container\ContainerInterface;
6-
use Selfoss\controllers;
79

810
require __DIR__ . '/src/common.php';
911

1012
/** @var ContainerInterface $container */
11-
$router = $container->get(Bramus\Router\Router::class);
12-
13-
// define routes
14-
15-
// all users
16-
$router->get('/', function() use ($container): void {
17-
// json
18-
$container->get(controllers\Index::class)->home();
19-
});
20-
$router->get('/api/about', function() use ($container): void {
21-
// json
22-
$container->get(controllers\About::class)->about();
23-
});
24-
$router->post('/api/private/hash-password', function() use ($container): void {
25-
// json
26-
$container->get(controllers\Helpers\HashPassword::class)->hash();
27-
});
28-
$router->get('/login', function() use ($container): void {
29-
// json, deprecated
30-
$container->get(controllers\Authentication::class)->login();
31-
});
32-
$router->post('/login', function() use ($container): void {
33-
// json
34-
$container->get(controllers\Authentication::class)->login();
35-
});
36-
$router->get('/logout', function() use ($container): void {
37-
// json, deprecated
38-
$container->get(controllers\Authentication::class)->logout();
39-
});
40-
$router->delete('/api/session/current', function() use ($container): void {
41-
// json
42-
$container->get(controllers\Authentication::class)->logout();
43-
});
44-
$router->get('/update', function() use ($container): void {
45-
// text
46-
$container->get(controllers\Sources\Update::class)->updateAll();
47-
});
48-
49-
// only for loggedin users or on public mode
50-
$router->get('/rss', function() use ($container): void {
51-
// rss
52-
$container->get(controllers\Rss::class)->rss();
53-
});
54-
$router->get('/feed', function() use ($container): void {
55-
// rss
56-
$container->get(controllers\Rss::class)->rss();
57-
});
58-
$router->get('/items', function() use ($container): void {
59-
// json
60-
$container->get(controllers\Items::class)->listItems();
61-
});
62-
$router->get('/tags', function() use ($container): void {
63-
// json
64-
$container->get(controllers\Tags::class)->listTags();
65-
});
66-
$router->get('/stats', function() use ($container): void {
67-
// json
68-
$container->get(controllers\Items\Stats::class)->stats();
69-
});
70-
$router->get('/items/sync', function() use ($container): void {
71-
// json
72-
$container->get(controllers\Items\Sync::class)->sync();
73-
});
74-
$router->get('/sources/stats', function() use ($container): void {
75-
// json
76-
$container->get(controllers\Sources::class)->stats();
77-
});
78-
79-
// only loggedin users
80-
$router->post('/mark/([0-9]+)', function(string $itemId) use ($container): void {
81-
// json
82-
$container->get(controllers\Items::class)->mark($itemId);
83-
});
84-
$router->post('/mark', function() use ($container): void {
85-
// json
86-
$container->get(controllers\Items::class)->mark();
87-
});
88-
$router->post('/unmark/([0-9]+)', function(string $itemId) use ($container): void {
89-
// json
90-
$container->get(controllers\Items::class)->unmark($itemId);
91-
});
92-
$router->post('/starr/([0-9]+)', function(string $itemId) use ($container): void {
93-
// json
94-
$container->get(controllers\Items::class)->starr($itemId);
95-
});
96-
$router->post('/unstarr/([0-9]+)', function(string $itemId) use ($container): void {
97-
// json
98-
$container->get(controllers\Items::class)->unstarr($itemId);
99-
});
100-
$router->post('/items/sync', function() use ($container): void {
101-
// json
102-
$container->get(controllers\Items\Sync::class)->updateStatuses();
103-
});
104-
105-
$router->get('/source/params', function() use ($container): void {
106-
// json
107-
$container->get(controllers\Sources::class)->params();
108-
});
109-
$router->get('/sources', function() use ($container): void {
110-
// json
111-
$container->get(controllers\Sources::class)->show();
112-
});
113-
$router->get('/sources/list', function() use ($container): void {
114-
// json
115-
$container->get(controllers\Sources::class)->listSources();
116-
});
117-
$router->post('/source/((?:new-)?[0-9]+)', function(string $id) use ($container): void {
118-
// json
119-
$container->get(controllers\Sources\Write::class)->write($id);
120-
});
121-
$router->post('/source', function() use ($container): void {
122-
// json
123-
$container->get(controllers\Sources\Write::class)->write();
124-
});
125-
$router->delete('/source/([0-9]+)', function(string $id) use ($container): void {
126-
// json
127-
$container->get(controllers\Sources::class)->remove($id);
128-
});
129-
$router->post('/source/delete/([0-9]+)', function(string $id) use ($container): void {
130-
// json, deprecated
131-
$container->get(controllers\Sources::class)->remove($id);
132-
});
133-
$router->post('/source/([0-9]+)/update', function(string $id) use ($container): void {
134-
// json
135-
$container->get(controllers\Sources\Update::class)->update($id);
136-
});
137-
$router->get('/sources/spouts', function() use ($container): void {
138-
// json
139-
$container->get(controllers\Sources::class)->spouts();
140-
});
141-
142-
$router->post('/tags/color', function() use ($container): void {
143-
// json
144-
$container->get(controllers\Tags::class)->color();
145-
});
146-
147-
$router->post('/opml', function() use ($container): void {
148-
// json
149-
$container->get(controllers\Opml\Import::class)->add();
150-
});
151-
$router->get('/opmlexport', function() use ($container): void {
152-
// xml
153-
$container->get(controllers\Opml\Export::class)->export();
154-
});
155-
156-
// Client side routes need to be directed to index.html.
157-
$router->get('/sign/in|/opml|/password|/manage/sources(/add)?|/(newest|unread|starred)(/(all|tag-[^/]+|source-[0-9]+)(/[0-9]+)?)?', function() use ($container): void {
158-
// html
159-
$container->get(controllers\Index::class)->home();
160-
});
161-
162-
$router->set404(function(): void {
163-
header('HTTP/1.1 404 Not Found');
164-
echo 'Page not found.';
165-
});
166-
167-
// dispatch
168-
$router->run();
13+
$routes = $container->get(Selfoss\Web\Routes::class);
14+
$routes->run();

src/Web/Routes.php

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
// SPDX-License-Identifier: GPL-3.0-or-later
6+
// SPDX-FileCopyrightText: 2011–2015 Tobias Zeising <tobias.zeising@aditu.de>
7+
// SPDX-FileCopyrightText: 2025 Jan Tojnar <jtojnar@gmail.com>
8+
9+
namespace Selfoss\Web;
10+
11+
use Bramus\Router\Router;
12+
use Psr\Container\ContainerInterface;
13+
use Selfoss\controllers;
14+
15+
/**
16+
* Defines API routes serving as an entry point to the web app.
17+
*/
18+
final class Routes {
19+
public function __construct(
20+
private Router $router,
21+
private ContainerInterface $container
22+
) {
23+
}
24+
25+
private function setupRoutes(): void {
26+
// all users
27+
$this->router->get('/', function(): void {
28+
// html/json
29+
$this->container->get(controllers\Index::class)->home();
30+
});
31+
$this->router->get('/api/about', function(): void {
32+
// json
33+
$this->container->get(controllers\About::class)->about();
34+
});
35+
$this->router->post('/api/private/hash-password', function(): void {
36+
// json
37+
$this->container->get(controllers\Helpers\HashPassword::class)->hash();
38+
});
39+
$this->router->get('/login', function(): void {
40+
// json, deprecated
41+
$this->container->get(controllers\Authentication::class)->login();
42+
});
43+
$this->router->post('/login', function(): void {
44+
// json
45+
$this->container->get(controllers\Authentication::class)->login();
46+
});
47+
$this->router->get('/logout', function(): void {
48+
// json, deprecated
49+
$this->container->get(controllers\Authentication::class)->logout();
50+
});
51+
$this->router->delete('/api/session/current', function(): void {
52+
// json
53+
$this->container->get(controllers\Authentication::class)->logout();
54+
});
55+
$this->router->get('/update', function(): void {
56+
// text
57+
$this->container->get(controllers\Sources\Update::class)->updateAll();
58+
});
59+
60+
// only for loggedin users or on public mode
61+
$this->router->get('/rss', function(): void {
62+
// rss
63+
$this->container->get(controllers\Rss::class)->rss();
64+
});
65+
$this->router->get('/feed', function(): void {
66+
// rss
67+
$this->container->get(controllers\Rss::class)->rss();
68+
});
69+
$this->router->get('/items', function(): void {
70+
// json
71+
$this->container->get(controllers\Items::class)->listItems();
72+
});
73+
$this->router->get('/tags', function(): void {
74+
// json
75+
$this->container->get(controllers\Tags::class)->listTags();
76+
});
77+
$this->router->get('/stats', function(): void {
78+
// json
79+
$this->container->get(controllers\Items\Stats::class)->stats();
80+
});
81+
$this->router->get('/items/sync', function(): void {
82+
// json
83+
$this->container->get(controllers\Items\Sync::class)->sync();
84+
});
85+
$this->router->get('/sources/stats', function(): void {
86+
// json
87+
$this->container->get(controllers\Sources::class)->stats();
88+
});
89+
90+
// only loggedin users
91+
$this->router->post('/mark/([0-9]+)', function(string $itemId): void {
92+
// json
93+
$this->container->get(controllers\Items::class)->mark($itemId);
94+
});
95+
$this->router->post('/mark', function(): void {
96+
// json
97+
$this->container->get(controllers\Items::class)->mark();
98+
});
99+
$this->router->post('/unmark/([0-9]+)', function(string $itemId): void {
100+
// json
101+
$this->container->get(controllers\Items::class)->unmark($itemId);
102+
});
103+
$this->router->post('/starr/([0-9]+)', function(string $itemId): void {
104+
// json
105+
$this->container->get(controllers\Items::class)->starr($itemId);
106+
});
107+
$this->router->post('/unstarr/([0-9]+)', function(string $itemId): void {
108+
// json
109+
$this->container->get(controllers\Items::class)->unstarr($itemId);
110+
});
111+
$this->router->post('/items/sync', function(): void {
112+
// json
113+
$this->container->get(controllers\Items\Sync::class)->updateStatuses();
114+
});
115+
116+
$this->router->get('/source/params', function(): void {
117+
// json
118+
$this->container->get(controllers\Sources::class)->params();
119+
});
120+
$this->router->get('/sources', function(): void {
121+
// json
122+
$this->container->get(controllers\Sources::class)->show();
123+
});
124+
$this->router->get('/sources/list', function(): void {
125+
// json
126+
$this->container->get(controllers\Sources::class)->listSources();
127+
});
128+
$this->router->post('/source/((?:new-)?[0-9]+)', function(string $id): void {
129+
// json
130+
$this->container->get(controllers\Sources\Write::class)->write($id);
131+
});
132+
$this->router->post('/source', function(): void {
133+
// json
134+
$this->container->get(controllers\Sources\Write::class)->write();
135+
});
136+
$this->router->delete('/source/([0-9]+)', function(string $id): void {
137+
// json
138+
$this->container->get(controllers\Sources::class)->remove($id);
139+
});
140+
$this->router->post('/source/delete/([0-9]+)', function(string $id): void {
141+
// json, deprecated
142+
$this->container->get(controllers\Sources::class)->remove($id);
143+
});
144+
$this->router->post('/source/([0-9]+)/update', function(string $id): void {
145+
// json
146+
$this->container->get(controllers\Sources\Update::class)->update($id);
147+
});
148+
$this->router->get('/sources/spouts', function(): void {
149+
// json
150+
$this->container->get(controllers\Sources::class)->spouts();
151+
});
152+
153+
$this->router->post('/tags/color', function(): void {
154+
// json
155+
$this->container->get(controllers\Tags::class)->color();
156+
});
157+
158+
$this->router->post('/opml', function(): void {
159+
// json
160+
$this->container->get(controllers\Opml\Import::class)->add();
161+
});
162+
$this->router->get('/opmlexport', function(): void {
163+
// xml
164+
$this->container->get(controllers\Opml\Export::class)->export();
165+
});
166+
167+
// Client side routes need to be directed to index.html.
168+
$this->router->get('/sign/in|/opml|/password|/manage/sources(/add)?|/(newest|unread|starred)(/(all|tag-[^/]+|source-[0-9]+)(/[0-9]+)?)?', function(): void {
169+
// html
170+
$this->container->get(controllers\Index::class)->home();
171+
});
172+
173+
$this->router->set404(function(): void {
174+
header('HTTP/1.1 404 Not Found');
175+
echo 'Page not found.';
176+
});
177+
}
178+
179+
public function run(): bool {
180+
$this->setupRoutes();
181+
182+
// dispatch
183+
return $this->router->run();
184+
}
185+
}

0 commit comments

Comments
 (0)